perm filename MANUAL.TEX[MF,DEK]16 blob
sn#772289 filedate 1984-10-23 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00018 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002 % This manual is copyright (C) 1984 by the American Mathematical Society.
C00005 00003 % halftitle
C00007 00004 % title
C00009 00005 % copyright
C00012 00006 % dedication
C00013 00007 % blank page
C00014 00008 % the preface
C00049 00009 % the table of contents
C00053 00010 \beginchapter Chapter 1. The Name of\\the Game
C00070 00011 \beginchapter Chapter 2. Coordinates
C00105 00012 \beginchapter Chapter 3. Curves
C00127 00013 \beginchapter Chapter 4. Pens
C00179 00014 \beginchapter Chapter 5. Running\\\MF
C00259 00015 \beginchapter Appendix A. Answers to\\All the\\Exercises
C00261 00016 \beginchapter Appendix J. Joining the\\\TeX\ Community
C00264 00017 \end
C00265 00018 \beginchapter Chapter X. A Chapter\\Template
C00266 ENDMK
C⊗;
% This manual is copyright (C) 1984 by the American Mathematical Society.
% All rights are reserved!
% The file is distributed only for people to see its examples of TeX input,
% not for use in the preparation of books like The METAFONTbook.
% Permission for any other use of this file must be obtained in writing
% from the copyright holder and also from the publisher (Addison-Wesley).
\let\MFmanual=\!
%\loop\iftrue
% \errmessage{This manual is copyrighted and should not be TeXed}\repeat
%\pausing1 \input manmac
%\ifproofmode\message{Proof mode is on!}\pausing1\fi
\input manmac[tex,dek]
% halftitle
\titlepage
\pageno=-1984
\line{\titlefont The {\manual ()*+,-.*}book}
\vfill
\ifproofmode
\rightline{The fine print in the upper right-hand}
\rightline{corner of each page is a draft of intended}
\rightline{index entries; it won't appear in the real book.}
\rightline{Some index entries will be in |typewriter type|}
\rightline{and/or enclosed in \<$\ldots$>, etc;}
\rightline{such typographic distinctions aren't shown here.}
\rightline{An index entry often extends for several pages;}
\rightline{the actual scope will be determined later.}
\rightline{Please note things that should be indexed but aren't.}
\fi
\eject
% title
\pageno=-1 % the front matter is numbered with roman numerals
\font\auth=amssmc10 scaled\magstep4 % used only on the title page
\font\elevenbf=ambx10 scaled\magstephalf % ditto
\font\elevenit=amti10 scaled\magstephalf % ditto
\font\elevenrm=amr10 scaled\magstephalf % ditto
\titlepage
\line{\titlefont The {\manual ()*+,-.*}book}
↑↑{Knuth, Donald Ervin}
↑↑{Bibby, Duane Robert}
\vskip 1pc
\baselineskip 13pt \elevenbf
\halign to\hsize{#\hfil\tabskip 0pt plus 1fil\hfil\tabskip0pt\cr
\kern1.5mm\auth DONALD \kern+2pt E. \kern+2pt KNUTH&
\elevenit Stanford University\cr
\noalign{\vskip 12pc}
&\elevenit I\kern.7ptllustrations by\cr
&DUANE BIBBY\cr
\noalign{\vfill}
&\setbox0=\hbox{\man\char'44\char'44}%
\setbox2=\hbox to\wd0{\hss\man\char'43\hss}%
\raise2.3mm\box2\kern-\wd0\box0\cr % A-W logo
&ADDISON-\kern-1pt WESLEY\cr
&PUBLISHING COMP\kern-.13emANY\kern-1.5mm\cr
\noalign{\vskip.5pc \global\elevenrm}
&Reading, Massachusetts\cr
&Menlo Park, California\cr
&London\enspace$\cdot$\enspace Amsterdam\cr
&Don Mills, Ontario\enspace$\cdot$\enspace Sydney\cr}
\eject
% copyright
\titlepage
\eightpoint
\vbox to 8pc{}
\noindent\strut
The quotation on page xxx is copyright $\copyright$ 19xx by Xxxx,
and used by permission.
\medskip
\noindent
\TeX\ is a trademark of the American Mathematical Society.
\bigskip\medskip
\noindent
{\bf Library of Congress cataloging in publication data}
\medskip
{\tt\halign{#\hfil\cr
Knuth, Donald Ervin (1938-\cr
\ \ \ The METAFONTbook.\cr
\noalign{\medskip}
\ \ \ Includes index.\cr
\ \ \ 1.~METAFONT (Computer system).\ \ 2.~Computerized\cr
typesetting.\ \ 3.~Typeface design.\ \ I.~Title.\cr
Z253.4.T47K58\ \ 1985\ \ \ \ \ \ \ \ \ 686.2\char13 xxxx\ \ \ \ \ \ 84-xxx\cr
ISBN 0-201-xxxxx-x\cr}}
\vfill
%\noindent
%{\sl \kern-1pt Second printing, Someday?}
%\smallskip
\noindent
Copyright $\copyright$ 1985 by the American Mathematical Society
\smallskip
\noindent
This book is published jointly by the American Mathematical Society
and Addison-\kern-1ptWesley Publishing Company.
All rights reserved. No part of this publication may be reproduced, stored in
a retrieval system, or transmitted, in any form or by any means,
electronic, mechanical, photocopying, recording, or otherwise, without
the prior written permission of the publishers. Printed in the United
States of America. Published simultaneously in Canada.
\medskip
\noindent
ISBN 0-201-xxxxx-x\par
\noindent
ABCDEFGHIJ--HA--89876543
↑↑{Knuth, Donald Ervin}
\eject
% dedication
\titlepage
\vbox to 8pc{}
\rightline{\strut\eightssi To Hermann Zapf}
↑↑{Zapf, Hermann}
\vskip2pt
\rightline{\eightssi Whose strokes are the best}
\vfill
\eject
% blank page
\titlepage
\null\vfill
\eject
% the preface
\titlepage
\def\rhead{Preface}
\vbox to 8pc{
\rightline{\titlefont Preface}\vss}
{\topskip 9pc % this makes equal sinkage throughout the Preface
\vskip-\parskip
\tenpoint
\noindent\hang\hangafter-2
\hbox to 0pt{\hskip-\hangindent\man\char'176\hfill}\hskip-16pt
{\sc ENERATION} {\sc OF} {\sc LETTERFORMS} \strut by mathematical means
was first tried in the fifteenth century; it became popular in the
sixteenth and seventeenth centuries; and it was abandoned (for good
reasons) during the eighteenth century. Perhaps the twentieth century
will turn out to be the right time for this idea to make a comeback,
now that mathematics has advanced and computers are able to
do the calculations.
Modern printing equipment based on raster lines---in which metal ``type''
has been replaced by purely combinatorial patterns of zeroes and ones
that specify the desired position of ink in a discrete way---makes
mathematics and computer science increasingly relevant to printing.
We now have the ability to give a completely precise definition of letter
shapes that will produce essentially equivalent results on all raster-based
machines. Furthermore it is possible to include variable parameters in the
definitions of those shapes; computers can ``draw'' new fonts of characters
in seconds, so that a designer is now able to perform valuable experiments
that were previously unthinkable.
\MF\ is a system for the design of alphabets suited to raster-based
devices that print or display text. The characters that you are reading
were all designed with \MF\!, in a completely precise way; and they
were developed rather hastily by the author of the system, who is a rank
amateur at such things. It seems clear that further work with \MF\ has
the potential of producing typefaces of real ↑{beauty}, so this manual has
been written for people who would like to help advance the art of
mathematical type design.
A top-notch designer of types needs to have an unusually good eye
and a highly developed sensitivity to the nuances of shapes.
A top-notch user of computer languages needs to have an unusual
talent for abstract reasoning and a highly-developed ability to
express intuitive ideas in formal terms. Very few people have both
of these unusual combinations of skills; hence the best products of
\MF\ will probably be collaborative efforts between two
people who complement each other's abilities. Indeed, this situation
isn't very different from the way types have been created for many
generations, except that the r\↑ole of ``punch-cutter'' is now being
played by skilled computer specialists instead of by skilled
metalworkers.
A \MF\ user writes a ``program'' for each letter or symbol that is
desired. These programs are different from ordinary computer programs,
because they are essentially {\sl declarative\/} rather than imperative.
In the \MF\ language you explain where the major components of a
desired shape are to be located, and how they relate to each other,
but you don't have to work out the details of exactly where the lines
cross, etc.; the computer takes over the work of solving equations as it
deduces the consequences of your specifications. One of the advantages of
\MF\ is that it provides a discipline according to which the principles
of a particular alphabet design can be stated precisely---the underlying
intelligence does not remain hidden in the mind of the designer, it is
spelled out in the programs. Thus it is comparatively easy to obtain
consistency where consistency is desirable, and to extend a font to
new symbols that are compatible with the existing ones.
It would be nice if a system like \MF\ were to simplify the task of
type design to the point where beautiful new alphabets could be
created in a few hours. This, alas, is impossible; an enormous
amount of subtlety lies behind the seemingly simple letter shapes that
we see every day, and the designers of high-quality typefaces have
done their work so well that we don't notice the underlying complexity.
One of the disadvantages of \MF\ is that a person can easily use it
to produce poor alphabets, cheaply and in great quantity. Let us hope
that such experiments will have educational value as they reveal why the
subtle tricks of the trade are important, but that they will not cause
bad workmanship to proliferate. Anybody can now produce a book in which
all of the type is home-made, but a person or team of persons should
expect to spend a year or more on the project if the type is actually
supposed to look right. \MF\ won't put today's type designers out of work;
on the contrary, it will tend to make them heroes, as more and more people
come to appreciate their skills.
Although there is no royal road to type design, there are some things that
can, in fact, be done well with \MF\ in an afternoon. Geometric designs
are rather easy; and it doesn't take long to make modifications to letters
or symbols that have previously been expressed in \MF\ form. Thus,
although comparatively few users of \MF\ will have the courage to do an
entire alphabet from scratch, there will be many who will enjoy
customizing someone else's design.
This book is not a text about mathematics or about computers. But if
you know the rudiments of those subjects (namely, contemporary high school
mathematics, together with the knowledge of how to use the text
editing or word processing facilities on your computing machine),
you should be able to use \MF\ with little difficulty after reading
what follows. Some parts of the exposition in the text are more obscure than others,
however, since the author has tried to satisfy experienced \MF\!ers
as well as beginners and casual users with a single manual. Therefore
a special symbol has been used to warn about esoterica: When you see the sign
$$\vbox{\hbox{\dbend}\vskip 11pt}$$
at the beginning of a paragraph, watch out for a ``↑{dangerous bend}''
in the train of thought---don't read such a paragraph unless you need to.
You will be able to use \MF\ reasonably well, even to design characters like
the dangerous-bend symbol itself, without reading the fine print in such
advanced sections.
Some of the paragraphs in this manual are so far out that they are rated
$$\vcenter{\hbox{\dbend\kern1pt\dbend}\vskip 11pt}\;;$$
everything that was said about single dangerous-bend signs goes double
for these. You should probably have at least a month's experience with
\MF\ before you attempt to fathom such doubly dangerous depths
of the system; in fact, most people will never need to know \MF\
in this much detail, even if they use it every day. After all, it's
possible to fry an egg without knowing anything about biochemistry.
Yet the whole story is here in case you're curious. \ (About \MF, not eggs.)
The reason for such different levels of complexity is that people change
as they grow accustomed to any powerful tool. When you first try to use
\MF\!, you'll find that some parts of it are very easy, while other things
will take some getting used to. At first you'll probably try to control
the shapes too rigidly, by overspecifying data that has been copied from
some other medium. But later, after you have begun to get a feeling for
what the machine can do well, you'll be a different person, and you'll be
willing to let \MF\ help contribute to your designs as they are being
developed. As you gain more and more experience working with this unusual
apprentice, your perspective will continue to change and you will be
running into different sorts of challenges. That's the way it is with any
powerful tool: There's always more to learn, and there are always better
ways to do what you've done before. At every stage in the development
you'll want a slightly different sort of manual. You may even want to
write one yourself. By paying attention to the dangerous bend signs in
this book you'll be better able to focus on the level that interests you
at a particular time.
Computer system manuals usually make dull reading, but take heart:
This one contains {\sc ↑{JOKES}} every once in a while. You might actually
enjoy reading it. \ (However, most of the jokes can only be appreciated
properly if you understand a technical point that is being made---so
read {\sl carefully}.)
Another noteworthy characteristic of this book is that it doesn't
always tell the ↑{truth}. When certain concepts of \MF\ are introduced
informally, general rules will be stated; afterwards you will find that the
rules aren't strictly true. In general, the later chapters contain more
reliable information than the earlier ones do. The author feels that this
technique of deliberate lying will actually make it easier for you to
learn the ideas. Once you understand a simple but false rule, it will not
be hard to supplement that rule with its exceptions.
In order to help you internalize what you're reading,
{\sc ↑{EXERCISES}} are sprinkled through this manual. It is generally intended
that every reader should try every exercise, except for questions that appear
in the ``dangerous bend'' areas. If you can't solve a problem, you
can always look up the answer.
But please, try first to solve it by yourself; then you'll learn more
and you'll learn faster. Furthermore, if you think you do know the solution,
you should turn to Appendix~A and check it out, just to make sure.
\bigskip
\hrule
\line{\vrule\hss\vbox{\medskip\ninepoint
\leftskip=\parindent \rightskip=\parindent
\noindent\strut W{\sc ARNING}: Type design can be hazardous to your other
interests. Once you get hooked, you will develop intense feelings about
letterforms; the medium will intrude on the messages that you read. And you
will perpetually be thinking of improvements to the fonts that you see
everywhere, especially those of your own design.
\strut\medskip}\hss\vrule}
\hrule
\bigskip
The \MF\ language described here has very little in common with the
author's previous attempt at a language for alphabet design, because
five years of experience with the old system has made it clear that a
completely different approach is preferable. Both languages have
been called \MF; but henceforth the old language should be called
\MF\kern.05em79, and its use should rapidly fade away. Let's keep the name \MF\
for the language described here, since it is so much better, and since
it will never change again. ↑↑{MF79}
I wish to thank the hundreds of people who have helped me to formulate
this ``definitive edition'' of \MF\!, based on their experiences with
preliminary versions of the system. In particular, John ↑{Hobby}
discovered many of the algorithms that have made the new language
possible. My work at Stanford has been generously supported by the
↑{National Science Foundation}, the ↑{Office of Naval Research}, the ↑{IBM
Corporation}, and the ↑{System Development Foundation}. I also wish to
thank the ↑{American Mathematical Society} for its encouragement and for
publishing the {\sl ↑{TUGboat}\/} newsletter (see Appendix~J).
Above all, I deeply thank my wife, Jill, for the inspiration, ↑↑{Knuth, Jill}
understanding, comfort, and support she has given me for more than
25~years, especially during the eight years that I have been
working intensively on mathematical typography.
\medskip
\line{{\sl Stanford, California}\hfil--- D. E. K.}↑↑{Knuth, Don}
\line{\sl June 1985\hfil}
} % end of the special \topskip
\endchapter
It is hoped that Divine Justice may find
some suitable affliction for the malefactors
who invent variations upon the alphabet of our fathers.~.\thinspace.\thinspace.
The type-founder, worthy mechanic, has asserted himself
with an overshadowing individuality,
defacing with his monstrous creations and revivals
every publication in the land.
\author AMBROSE ↑{BIERCE}, {\sl The Opinionator.~Alphab\↑etes\/} %
(1911) % vol 10 of his collected works, p69
% probably written originally in 1898 or 1899
\bigskip
Can the new process yield a result that, say,
a Club of Bibliophiles would recognise as a work of art
comparable to the choice books they have in their cabinets?
\author STANLEY ↑{MORISON}, {\sl Typographic Design in Relation to
Photographic Composition\/} (1958) % pp 4--5
\eject
% the table of contents
\titlepage
\vbox to 8pc{
\rightline{\titlefont Contents}
\vfill}
↑↑{Contents of this manual, table}
\def\rhead{Contents}
\tenpoint
\begingroup
\countdef\counter=255
\def\diamondleaders{\global\advance\counter by 1
\ifodd\counter \kern-10pt \fi
\leaders\hbox to 20pt{\ifodd\counter \kern13pt \else\kern3pt \fi
.\hss}}
\baselineskip 15pt plus 5pt
\def\\#1. #2. #3.{\line{\strut
\hbox to\parindent{\bf\hbox to 1em{\hss#1}\hss}%
\rm#2\diamondleaders\hfil\hbox to 2em{\hss#3}}}
\\1. The Name of the Game. 1.
\\2. Coordinates. 5.
\\3. Curves. 13.
\\4. Pens. 21.
\\5. Running \MF. 33.
\\6. How \MF\ Reads What You Type. xx.
\\7. Seventhly. xx.
\\8. XXX. xxx.
\\9. All These Titles are Garbage. xxx.
\\10. Dimensions. 57.
\\11. Boxes. 63.
\\12. Glue. 69.
\\13. Modes. 85.
\\14. How \MF\ Breaks Paragraphs into Lines. 91.
\\15. How \MF\ Makes Lines into Pages. 109.
\\16. Typing Math Formulas. 127.
\\17. More about Math. 139.
\\18. Fine Points of Mathematics Typing. 161.
\\19. Displayed Equations. 185.
\\20. Definitions (also called Macros). 199.
\\21. Making Boxes. 221.
\\22. Alignment. 231.
\\23. Output Routines. 251.
\eject
\vbox to 8pc{}
\\24. Summary of Normal Mode. 267.
\\25. Summary of Abnormal Mode. 285.
\\26. Summary of Everything Else. 287.
\\27. Recovering from Errors. 289.
\null
\leftline{\indent\bf Appendices}
\\A. Answers to All the Exercises. xxx.
\\B. Basic Operations. xxx.
\\C. Character Codes. xxx.
\\D. Dirty Tricks. xxx.
\\E. Examples. xxx.
\\F. Font Metric Information. xxx.
\\G. Generic Font Files. xxx.
\\H. Hardcopy Proofs. xxx.
\\I\hskip 1pt. Index. xxx.
\\J. Joining the \TeX\ Community. xxx.
\null % 17 lines so far to balance the 23 on the other page
\null % 18
\null % 19
\null % 20
\null % 21
\null % 22
\null % 23
\eject
\endgroup
\beginchapter Chapter 1. The Name of\\the Game
\pageno=1 % This is page number 1, number 1,
This is a book about a computer system called \MF\!, just as {\sl The \TeX
book\/} is about \TeX. \MF\ and \TeX\ are good friends who intend to live
together for a long time. Between them they take care of the two most
fundamental tasks of typesetting: \TeX\ puts characters into the proper
positions on a page, while \MF\ determines the shapes of the characters
themselves. ↑↑{TeX} ↑↑{METAFONT, the name}
Why is the system called \MF\thinspace? The `-{\manual FONT}\thinspace'
part is easy to understand, because sets of related characters that are
used in typesetting are traditionally known as fonts of type. The
`{\manual META}-' part is more interesting: It indicates that we are
interested in making high-level descriptions that transcend any of the
individual fonts being described.
Newly coined words beginning with `meta-' generally reflect our contemporary
inclination to view things from outside or above, at a more abstract level than
before, with what we feel is a more mature understanding. We now have
metapsychology (the study of how the mind relates to its containing body),
metahistory (the study of principles that control the course of events),
metamathematics (the study of mathematical reasoning), metafiction
(literary works that explicitly acknowledge their own forms), and so on.
A metamathematician proves metatheorems (theorems about theorems);
a computer scientist often works with metalanguages (languages for
describing languages). Similarly, a ↑{meta-font} is a schematic description
of the shapes in a family of related fonts; the letterforms change
appropriately as their underlying parameters change.
Meta-design is much more difficult than design; it's easier to draw something
than to explain how to draw it. One of the problems is that it's hard to
envision many different sets of potential specifications all at once;
another is that a computer has to be told absolutely everything.
However, once we have successfully explained how to draw something
in a sufficiently general manner, the same explanation will work for
related shapes, in different circumstances; so~the time spent in formulating
a precise explanation turns out to be worth it.
Typefaces intended for text are normally seen small, and our eyes can read
them best when the letters have been designed specifically for the size at
which they are actually used. Although it is tempting to get 7-point fonts
by simply making a 70\% reduction from the 10-point size, this shortcut
leads to a serious degradation of quality. Much better results can be
obtained by incorporating parametric variations into a meta-design. In
fact, there are advantages to built-in variability even when you want to
produce only one font of type in a single size, because it allows you to
postpone making decisions about many aspects of your design. If you leave
certain things undefined, treating them as parameters instead of
``freezing'' the specifications at an early stage, the computer will be
able to draw lots of examples with different settings of the parameters,
and you will be able to see the results of all those experiments at the final
size. This will greatly increase your ability to edit and fine-tune the font.
If meta-fonts are so much better than plain old ordinary fonts, why weren't
they developed long ago? The main reason is that computers did not exist until
recently. People find it difficult and dull to carry out calculations with
a multiplicity of parameters, while today's machines do such tasks with ease.
The introduction of parameters is a natural outgrowth of automation.
OK, let's grant that meta-fonts sound good, at least in theory. There's still
the practical problem about how to achieve them. How can we actually
specify shapes that depend on unspecified parameters?
If only one parameter is varying, it's fairly easy to solve the problem in
a visual way, by overlaying a series of drawings that show graphically how
the shape changes. For example, if the parameter varies from 0 to~1, we
might prepare five sketches, corresponding to the parameter values 0,
$1\over4$, $1\over2$, $3\over4$, and~1. If these sketches follow a
consistent pattern, we can readily interpolate to find the shape for a
value like~$2\over3$ that lies between two of the given ones. We might
even try extrapolating to parameter values like 1$1\over4$.
But if there are two or more independent parameters, a purely visual solution
becomes too cumbersome. We must go to a verbal approach, using some sort
of language to describe the desired drawings. Let's imagine, for example,
that we want to explain the shape of a certain letter `a' to a friend in
a distant country, using only a telephone for communication; our friend
is supposed to be able to reconstruct exactly the shape we have in mind.
Once we figure out a sufficiently natural way to do that, for a particular
fixed shape, it isn't much of a trick to go further and make our verbal
description more general, by including variable parameters instead of
restricting ourselves to constants.
An analogy to cooking might make this point clearer. Suppose you have just
baked a delicious berry pie, and your friends ask you to tell them the
↑{recipe} so that they can bake one too. If you have developed your cooking
skills entirely by instinct, you might find it difficult to record exactly
what you did. But there is a traditional language of recipes in which you
could communicate the steps you followed; and if you take careful measurements,
you might find that you used, say, 1$1\over4$ cups of sugar. The next step,
if you were instructing a computer-controlled cooking machine, would be to
go to a meta-recipe in which you use, say, $.25x$ cups of sugar for $x$
cups of berries; or $.3x+.2y$ cups for $x$~cups of boysenberries and
$y$~cups of blackberries.
In other words, going from design to meta-design is essentially like
going from arithmetic to elementary algebra: Numbers are replaced
by simple formulas that involve unknown quantities. We will see
many examples of this.
A \MF\ definition of a complete typeface generally consists of three
main parts. First there is a rather mundane set of subroutines that take care
of necessary administrative details, such as assigning code numbers
to individual characters; each character must also
be positioned properly inside an invisible ``box,'' so that typesetting
systems will produce the correct spacing. Next comes a more interesting
collection of subroutines, designed to draw the basic strokes characteristic
of the typeface (e.g., the serifs, bowls, arms, arches, and so on).
These subroutines will typically be described in terms of their own special
parameters, so that they can produce a variety of related strokes;
a serif subroutine will, for example, be able to draw serifs of
different lengths, although all of the serifs it draws should
have the same ``feeling.'' Finally, there are routines for each of
the characters. If the subroutines in the first and second parts have been
chosen well, the routines of the third part will be fairly high-level descriptions
that don't concern themselves unnecessarily with details; for example, it
may be possible to substitute a different serif-drawing subroutine without
changing any of the programs that use that subroutine, thereby obtaining
a typeface of quite a different flavor. [A particularly striking example
of this approach has been worked out by John~D. ↑{Hobby} and ↑{Gu} Guoan
in ``A Chinese Meta-Font,'' {\sl TUGboat\/ \bf5} (1984), xx--xx. By
changing a set of 13 basic stroke subroutines, they were able to draw 128
sample ↑{Chinese characters} in three different styles (Song, Long Song,
and Bold), using the same programs for the characters.]
A well-written \MF\ program will express the designer's intentions more
clearly than mere drawings ever can, because the language of algebra has
simple ``idioms'' that make it possible to elucidate many visual relationships.
Thus, \MF\ programs can be used to communicate knowledge
about type design, just as recipes convey the expertise of a chef. But
algebraic formulas are not easy to understand in isolation; \MF\ descriptions
are meant to be read with an accompanying illustration, just as the
constructions in geometry textbooks are accompanied by diagrams.
Nobody is ever expected to read the text of a \MF\ program and say,
``Ah, what a beautiful letter!'' But with one or more enlarged pictures
of the letter, based on one or more settings of the parameters, a reader
of the \MF\ program should be able to say, ``Ah, I~understand how this
beautiful letter was drawn!'' We shall see that the \MF\ system makes it
fairly easy to obtain annotated proof drawings that you can hold in your
hand as you are working with a program.
Although \MF\ is intended to provide a relatively painless way to describe
meta-fonts, you can of course use it also to describe unvarying shapes that
have no ``meta-ness'' at all. Indeed, you need not even use it to produce
fonts; the system will happily draw geometric designs that have no relation
to the characters or glyphs of any alphabet or script. The author
occasionally uses \MF\ simply as a pocket calculator, to do elementary
arithmetic in an interactive way. A computer doesn't mind if its
programs are put to purposes that don't match their names.
\endchapter
[Tinguely] made some large, brightly coloured open reliefs,
juxtaposing stationary and mobile shapes.
He later gave them names like\/ %
{\rm Meta-↑{Kandinsky}}\kern-1pt\ and\/ {\rm Meta-↑{Herbin}}\kern-.5pt,
to clarify the ideas and attitudes %
that lay at the root of their conception.
\author K. G. PONTUS ↑{HULT\'EN}, {\sl Jean ↑{Tinguely}: M\'eta\/} (1972)
% translated from German by Mary Whittall, 1975, p46
\bigskip
The idea of a meta-font shoud now be clear. But what good is it?
The ability to manipulate lots of parameters may be interesting and fun,
but does anybody really need a 6\/$\scriptstyle{\mkern2mu 3\mkern-2mu\over %
\mkern-2mu 7\mkern2mu}$-point font
that is one fourth of the way between Baskerville and Helvetica?
\author DONALD E. ↑{KNUTH}, {\sl The Concept of a Meta-Font\/} (1982)
% Visible Language 16, p19
\eject
\beginchapter Chapter 2. Coordinates
If we want to tell a computer how to draw a particular shape, we need a way to
explain where the key points of that shape are supposed to appear.
\MF\ uses standard {\sl ↑{Cartesian} ↑{coordinates}\/} for this purpose:
The location of a point is defined by specifying its $x$~coordinate, which
is the number of units to the right of some reference point, and its
$y$~coordinate, which is the number of units upwards from the reference
point. First we determine the horizontal (left/right) component of a
point's position, then we determine the vertical (up/down) component.
\MF's world is two-dimensional, so two coordinates are enough.%
↑↑{x coordinate} ↑↑{y coordinate}
For example, let's consider the following six points:
\displayfig 2a (4.75pc)
\MF's names for the positions of these points are
\begindisplay
$(x↓1,y↓1)=(0,100)$;&$(x↓2,y↓2)=(100,100)$;&$(x↓3,y↓3)=(200,100)$;\cr
$(x↓4,y↓4)=(0,\hfill0)$;&$(x↓5,y↓5)=(100,\hfill0)$;&
$(x↓6,y↓6)=(200,\hfill0)$.\cr
\enddisplay
Point 4 is the same as the reference point, since both of its coordinates
are zero; to get to point~$3=(200,100)$, you start at the reference point
and go 200~steps right and 100~up; and so on.
\exercise Which of the six example points is closest to the point $(60,30)$?
\answer Point $5=(100,0)$ is closer than any of the others. \ (See
the diagram below.)
\exercise True or false: All points that lie on a given horizontal straight
line have the same $x$~coordinate.
\answer \decreasehsize 15pc
\rightfig A2a (13pc x 5pc) ↑9pt
False. But they all do have the same $y$~coordinate.
\exercise Explain where the point $(-5,15)$ is located.
\answer 5 units to the {\sl left\/} of the reference point, and 15 units up.
\exercise What are the coordinates of a point that lies exactly
60~units below point~6 in the diagram above?
(``Below'' means ``down the page,'' not ``under the page.'')
\answer \restorehsize $(200,-60)$.
In a typical application of \MF\!, you prepare a rough sketch of the shape
you plan to define, on a piece of ↑{graph paper}, and you label important
points on that sketch with any convenient numbers. Then you write a \MF\
program that explains (i)~the coordinates of those key points, and
(ii)~the lines or curves that are supposed to go between them.
\MF\ has its own internal graph paper, which forms a so-called ↑{raster}
or ↑{grid} consisting of square ``↑{pixels}.'' ↑↑{pel, see pixel}
The output of \MF\ will \hbox{specify} that certain of the pixels are ``black''
and that the others are ``white''; thus, the computer essentially converts
shapes into binary patterns like the designs a~person can make when doing
needlepoint with two colors of yarn.
Coordinates are lengths, but we haven't discussed yet what the units of
length actually are. It's important to choose convenient units,
and \MF's coordinates are given in units of pixels. The little squares
illustrated on the previous page, which correspond to differences
of 10~units in an $x$~coordinate or a $y$~coordinate, therefore represent
$10\times10$ arrays of pixels, and the rectangle enclosed by our six
example points contains 20,000 pixels altogether.\footnote*{We
sometimes use the term ``pixel'' to mean a square picture element,
but sometimes we use it to signify a one-dimensional unit of length.
A square pixel is one pixel-unit wide and one pixel-unit tall.}
Coordinates don't have to be whole numbers. You can refer, for example,
to point $(31.5,42.5)$, which lies smack in the middle of the pixel
whose corners are at $(31,42)$, $(31,43)$, $(32,42)$, and~$(32,43)$.
The computer works internally with coordinates that are integer multiples
of ${1\over65536}\approx0.00002$ of the width of a pixel, so it is
capable of making very fine distinctions. But \MF\ will never make
a pixel half black; it's all or nothing, as far as the output is concerned.
The fineness of a grid is usually called its {\sl ↑{resolution}}, and
resolution is usually expressed in pixel units per inch (in America)
or pixel units per millimeter (elsewhere). For example, the type you
are now reading was prepared by \MF\ with a resolution of slightly
more than 700 pixels to the inch, but with slightly fewer than 30 pixels
per~mm. For the time being we shall assume that the pixels are so tiny
that the operation of rounding to whole pixels is unimportant;
later we will consider the important questions that arise when \MF\ is
producing low-resolution output.
It's usually desirable to write \MF\ programs that can manufacture fonts
at many different resolutions, so that a variety of low-resolution printing
devices will be able to make proofs that are compatible with a variety of
high-resolution devices. Therefore the key points in \MF\ programs are rarely
specified in terms of pure numbers like `100'\thinspace; we generally make
the coordinates relative to some other resolution-dependent quantity, so
that changes will be easy to make. For example, it would have been better
to use a definition something like the following, for the six points
considered earlier:
\begindisplay
$(x↓1,y↓1)=(0,b)$;&$(x↓2,y↓2)=(a,b)$;&$(x↓3,y↓3)=(2a,b)$;\cr
$(x↓4,y↓4)=(0,0)$;&$(x↓5,y↓5)=(a,0)$;&$(x↓6,y↓6)=(2a,0)$;\cr
\enddisplay
then the quantities $a$ and $b$ can be defined in some way appropriate to
the desired resolution. We had $a=b=100$ in our previous example, but
such constant values leave us with little or no flexibility.
Notice the quantity `$2a$' in the definitions of $x↓3$ and $x↓6$; \MF\
understands enough algebra to know that this means twice the value of~$a$,
whatever $a$~is. We observed in Chapter~1 that simple uses of algebra give
\MF\ its meta-ness. Indeed, it is interesting to note from a historical
standpoint that ↑{Cartesian} coordinates are named after Ren\'e
↑{Descartes}, not because he invented the idea of coordinates, but because
he showed how to get much more out of that idea by applying algebraic
methods. People had long since been using coordinates for such things as
latitudes and longitudes, but Descartes observed that by putting unknown
quantitities into the coordinates it became possible to describe infinite
sets of related points, and to deduce properties of curves that were
extremely difficult to work out using geometrical methods alone.
So far we have specified some points, but we haven't actually done
anything with them. Let's suppose that we want to draw a straight line
from point~1 to point~6, obtaining
\displayfig 2b (5pc)
One way to do this with \MF\ is to say
\begindisplay
@draw@ $(x↓1,y↓1)\to(x↓6,y↓6)$.
\enddisplay
The `$\to$' ↑↑{..} here tells the computer to connect two points.
It turns out that we often want to write formulas like `$(x↓1,y↓1)$', so
it will be possible to save lots of time if we have a special abbreviation
for such things. Henceforth we shall use the notation $z↓1$ to stand for
$(x↓1,y↓1)$, and in general ↑↑{z convention}
$z↓k$ with an arbitrary subscript will stand for the point $(x↓k,y↓k)$.
The `@draw@' command above can therefore be written more simply as
\begindisplay
↑@draw@ $z↓1\to z↓6$.
\enddisplay
Adding two more straight lines by saying, `@draw@ $z↓2\to z↓5$' and
`@draw@ $z↓3\to z↓4$', we obtain a design that is slightly reminiscent of
the ↑{Union Jack}:
\displayfig 2c (5.5pc)
We shall call this a ↑{hex symbol}, because it has six endpoints. Notice
that the straight lines here have some thickness, and they are rounded at
the ends as if they had been drawn with a felt-tip pen having a circular
nib. \MF\ provides many ways to control the thicknesses of lines and to
vary the terminal shapes, but we shall discuss such things in later
chapters because our main concern right now is to learn about coordinates.
If the hex symbol is scaled down so that its height parameter $b$
is exactly equal to the height of the letters in this paragraph,
it looks like this: `\thinspace{\manual\hexa}\thinspace'. Just for fun,
let's try to typeset ten of them in a row:
\begindisplay
{\manual\hexa\hexa\hexa\hexa\hexa\hexa\hexa\hexa\hexa\hexa}
\enddisplay
How easy it is to do this!\footnote*{Now that authors have
for the first time the power to invent new symbols with great ease, and to
have those characters printed in their manuscripts on a wide variety of
typesetting devices, we must face the question of how much experimentation
is desirable. Will font freaks abuse this toy by overdoing it? Is it wise
to introduce new symbols by the thousands? Such questions are beyond
the scope of this manual; but it is easy to imagine an epidemic of
fontomania occurring, once people realize how much fun it is to design
their own characters, hence it may be necessary to perform fontal
lobotomies.} % This joke due to Richard Palais, commenting on draft in 1979
Let's look a bit more closely at this new character.
The {\manual\hexa} is a bit too tall, because it extends above points
1, 2, and~3 when the thickness of the lines is taken into account;
similarly, it sinks a bit too much below the baseline (i.e., below
the line $y=0$ that contains points 4, 5, and~6). In order to correct
this, we want to move the key points slightly. For example, point~$z↓1$
should not be exactly at $(0,b)$, but let's arrange things so that
the top of the pen is at $(0,b)$ when the center of the pen is at~$z↓1$.
We can express this condition for the top three points as follows:
\begindisplay
$"top"\,z↓1=(0,b)$;&$"top"\,z↓2=(a,b)$;&$"top"\,z↓3=(2a,b)$;\cr
\noalign{\vskip\belowdisplayskip
\leftline{similarly, the remedy for points 4, 5, and 6 is to specify
the equations}
\vskip\abovedisplayskip}
$"bot"\,z↓4=(0,0)$;&$"bot"\,z↓5=(a,0)$;&$"bot"\,z↓6=(2a,0)$.\cr
\enddisplay
The resulting squashed-in character is
\displayfig 2d (4.5pc)
(shown here with the original weight `\thinspace{\manual\hexb}\thinspace'
and also in a bolder version `\thinspace{\manual\hexc}\thinspace').
\exercise Ten of these bold hexes produce `\thinspace{\manual
\hexc\hexc\hexc\hexc\hexc\hexc\hexc\hexc\hexc\hexc}\thinspace'; notice that
adjacent symbols overlap each other. The reason is that each character
has width $2a$, hence point~3 of one character coincides with point~1
of the next. Suppose that we actually want the characters to be
completely confined to a rectangular box of width~$2a$, so that
adjacent characters come just shy of touching (\thinspace{\manual
\hexd\hexd\hexd\hexd\hexd\hexd\hexd\hexd\hexd\hexd}\thinspace).
Try to guess how the point-defining equations above could be modified
to make this happen, assuming that
\MF\ has operations `"lft"' and `"rt"' analogous to `"top"' and `"bot"'.
\answer $"top"\,"lft"\,z↓1=(0,b)$; \ $"top"\,z↓2=(a,b)$; \
$"top"\,"rt"\,z↓3=(2a-1,b)$; \ $"bot"\,"lft"\,z↓4=(0,0)$; \
$"bot"\,z↓5=(a,0)$; \ $"bot"\,"rt"\,z↓6=(2a-1,0)$.
Adjacent characters will be separated by exactly one column of white
pixels, if character is $2a$ pixels wide, because the right edge of
black pixels is specified here to have the $x$~coordinate $2a-1$.
Pairs of coordinates can be thought of as ``↑{vectors}'' or ``displacements''
as well as points. For example, $(15,8)$ can be regarded as a command to
go right~15 and up~8; then point $(15,8)$ is the position we get to after
starting at the reference point and obeying the command $(15,8)$. This
interpretation works out nicely when we consider addition of vectors:
If we move according to the vector $(15,8)$ and then move according to
$(7,-3)$, the result is the same as if we move $(15,8)+(7,-3)=
(15+7,8-3)=(22,5)$. The sum of two vectors $z↓1=(x↓1,y↓1)$ and $z↓2=
(x↓2,y↓2)$ is the vector $z↓1+z↓2=(x↓1+x↓2,y↓1+y↓2)$ obtained by adding
$x$ and $y$ components separately. This vector represents the result of
moving by vector $z↓1$ and then moving by vector $z↓2$; alternatively,
$z↓1+z↓2$ represents the point you get~to by starting at point~$z↓1$
↑↑{addition of vectors}
and moving by vector~$z↓2$.
\exercise Consider the four fundamental vectors $(0,1)$, $(1,0)$,
$(0,-1)$, and $(-1,0)$. Which of them corresponds to moving one pixel unit
(a)~to the right? (b)~to the left? (c)~down? (d)~up?
\answer $"right"=(1,0)$; $"left"=(-1,0)$; $"down"=(0,-1)$; $"up"=(0,1)$.
Vectors can be subtracted as well added; the value of $z↓1-z↓2$ is simply
$(x↓1-x↓2,y↓1-y↓2)$. Furthermore it is natural to multiply a vector
by a single number~$c$: The quantity $c$~times $(x,y)$, which is written $c(x,y)$,
equals $(cx,cy)$. Thus, for example, $2z=2(x,y)=(2x,2y)$ turns out
to be equal to $z+z$. ↑↑{multiplication of vector by scalar}
In the special case $c=-1$ we write $-(x,y)=(-x,-y)$. ↑↑{negation of vectors}
Now we come to an important notion, based on the fact that subtraction
is the opposite of addition. {\sl If $z↓1$ and $z↓2$ are any two points,
then $z↓2-z↓1$ is the vector that corresponds to moving from $z↓1$ to~$z↓2$.}
The reason is simply that $z↓2-z↓1$ is what we must add to~$z↓1$ in order
to get~$z↓2$: i.e., $z↓1+(z↓2-z↓1)=z↓2$. We shall call this the
{\sl ↑{vector subtraction principle}}. ↑↑{subtraction of vectors}
It is used frequently in \MF\ programs when the designer wants to specify the
direction and/or distance of one point from another.
\MF\ programs often use another idea to express relations between points.
Suppose we start at point~$z↓1$ and travel in a straight line from there
in the direction of point~$z↓2$, but we don't go all the way. There's a
special notation for this, using square brackets: ↑↑{bracket notation}
\begindisplay \advance\baselineskip by 3pt
${1\over3}[z↓1,z↓2]$ is the point one-third of the way from $z↓1$ to $z↓2$,\cr
${1\over2}[z↓1,z↓2]$ is the point midway between $z↓1$ and $z↓2$,\cr
$.8[z↓1,z↓2]$ is the point eight-tenths of the way from $z↓1$ to $z↓2$,\cr
\enddisplay
and, in general, $t[z↓1,z↓2]$ stands for the point that lies a fraction
$t$ of the way from $z↓1$ to~$z↓2$. We call this the operation of {\sl
↑{mediation}\/} between points, or (informally) the ``↑{of-the-way
function}.'' If the fraction~$t$ increases from 0 to~1, the expression
$t[z↓1,z↓2]$ traces out a straight line from $z↓1$ to~$z↓2$. According to
the vector subtraction principle, we must move $z↓2-z↓1$ in order to go
all the way to $z↓1$ to~$z↓2$, hence the point $t$~of~the~way between them is
\begindisplay
$t[z↓1,z↓2]\;=\;z↓1+t(z↓2-z↓1)$.
\enddisplay
This is a general formula by which we can calculate $t[z↓1,z↓2]$ for any
given values of $t$, $z↓1$, and~$z↓2$. But \MF\ has this formula built~in,
so we can use the bracket notation explicitly.
For example, let's go back to our first six example points, and suppose
that we want to refer to the point that's 2/5 of the way from
$z↓2=(100,100)$ to $z↓6=(200,0)$. In \MF\ we can write this simply as
$.4[z↓2,z↓6]$. And if we need to compute the exact coordinates for some
reason, we can always work them out from the formula above, getting
$z↓2+.4(z↓6-z↓2)=(100,100)+.4\bigl((200,0)-(100,100)\bigr)=(100,100)
+.4(100,-100)=(100,100)+(40,-40)=(140,60)$.
\exercise True or false: The direction vector from $(5,-2)$ to $(2,3)$
is $(-3,5)$.
\answer True; this is $(2,3)-(5,-2)$.
\exercise Explain what the notation `$0[z↓1,z↓2]$' means, if anything.
What about `$1[z↓1,z↓2]$'? And `$2[z↓1,z↓2]$'? And `$(-.5)[z↓1,z↓2]$'?
\answer $0[z↓1,z↓2]=z↓1$, because we move none of the way towards~$z↓2$;
similarly $1[z↓1,z↓2]$ simplifies to~$z↓2$, because we move all of the
way. If we keep going in the same direction until we've gone twice as far
as the distance from $z↓1$ to~$z↓2$, we get to $2[z↓1,z↓2]$. But if we
start at point~$z↓1$ and face~$z↓2$, then back up exactly half the distance
between them, we wind up at $(-.5)[z↓1,z↓2]$.
\exercise True or false, for mathematicians: (a)~${1\over2}[z↓1,z↓2]=
{1\over2}(z↓1+z↓2)$; \ (b)~${1\over3}[z↓1,z↓2]={1\over3}z↓1+{2\over3}z↓2$;
\ (c)~$t[z↓1,z↓2]=(1-t)[z↓2,z↓1]$.
\answer (a)~True; both are equal to $z↓1+{1\over2}(z↓2-z↓1)$.
(b)~False, but close; the right-hand side should be
${2\over3}z↓1+{1\over3}z↓2$. (c)~True; both are equal to $(1-t)z↓1+tz↓2$.
\setbox0=\vtop{\kern -6pt
\rightline{\rlap{\vbox to 250\apspix{
\setbox2=\vbox{\kern-1pt
\hbox{\tenex\char'77} % vertical arrow extension module
\kern-1pt}
\offinterlineskip
\vbox{\hbox{\tenex\char'170}\kern0pt} % arrowhead at top
\cleaders\copy2\vfill
\kern3pt
\hbox to\wd2{\hss$b$\hss}
\kern3pt
\cleaders\copy2\vfill
\vbox{\hbox{\tenex\char'171}\kern0pt} % arrowhead at bottom
}}\kern 30\apspix
\vbox{\kern-.2pt \hrule \kern-.2pt
\hbox{\kern-.2pt \vrule \kern-.2pt
\kern30\apspix\figbox{2e}{150\apspix}{250\apspix}\vbox
\kern30\apspix\kern-.2pt\vrule \kern-.2pt}
\kern-.2pt \hrule \kern-.2pt}\quad}
\kern2pt
\rightline{\hbox to 30\apspix{\kern-.2pt\vrule height 7pt depth 2pt
\hfil$s$\hfil\vrule\kern-.2pt}%
\hbox to 150\apspix{\leftarrowfill$\,a\,$\rightarrowfill}%
\hbox to 30\apspix{\kern-.2pt\vrule height 7pt depth 2pt
\hfil$s$\hfil\vrule\kern-.2pt}\quad}}
\dp0=0pt
\hangindent-300\apspix \hangafter-13
Let's conclude \strut\vadjust{\box0}%
this chapter by using mediation
to help specify the five points in the stick-figure `{\manual\Aa}'
shown enlarged at the right. The distance between points 1 and~5
should be~$a$, and point~3 should be $b$ pixels above the baseline;
these values $a$ and~$b$ have been predetermined by some method
that doesn't concern us here, and so has a ``↑{sidebar}'' parameter~$s$
that specifies the horizontal distance of points 1 and~5 from the
edges of the type. We shall assume that we don't know for sure what
the height of the bar line should be; point~2 should be somewhere on the
straight line from point~1 to point~3, and point~4 should be in the
corresponding place between 5 and~3, but we want to try several
possibilities before we make a decision.
The width of the character will be $s+a+s$, and we can specify points
$z↓1$ and $z↓5$ by the equations
\begindisplay
$"bot"\,z↓1=(s,0)$;\qquad $z↓5=z↓1+(a,0)$.
\enddisplay
There are other ways to do the job, but these formulas clearly express
our intention to have the bottom of the pen at the baseline, $s$ pixels
to the right of the reference point, when the pen at~$z↓1$,
and to have $z↓5$ exactly $a$~pixels to the right of~$z↓1$.
Next, we can say
\begindisplay
$z↓3=\bigl({1\over2}[x↓1,x↓5],b\bigr)$;
\enddisplay
this means that the $x$ coordinate of point 3 should be halfway between
the $x$~coordinates of points 1 and~5, and that $y↓3=b$. Finally, let's say
\begindisplay
$z↓2="alpha"[z↓1,z↓3]$;\qquad $z↓4="alpha"[z↓5,z↓3]$;
\enddisplay
the parameter "alpha" is a number between 0 and~1 that governs the
position of the bar line, and it will be supplied later. When "alpha"
has indeed received a value, we can say
\begindisplay
@draw@ $z↓1\to z↓3$;\qquad @draw@ $z↓3\to z↓5$;\qquad @draw@ $z↓2\to z↓4$.
\enddisplay
\MF\ will draw the characters `{\manual\sevenAs}' when "alpha" varies
from 0.2 to 0.5 in steps of 0.05 and when $a=150$, $b=250$, $s=30$.
\danger (Are you sure you should be reading this paragraph? The
``↑{dangerous bend}'' sign here is meant to warn you about material that
ought to be skipped on first reading. And maybe also on second reading.
The reader-beware paragraphs sometimes refer to concepts that aren't
explained until later chapters.)
\dangerexercise Why is it better to define $z↓3$ as shown above, rather
than to work out the coordinates $z↓3=(s+{1\over2}a,\,b)$ that are implied
by the other equations?
\answer There are several reasons. (1)~The equations in a \MF\ program
should represent the programmer's intentions as directly as possible;
it's hard to understand those intentions if you are shown only
their ultimate consequences, since it's not easy to reconstruct algebraic
manipulations that have gone on behind the scenes. (2)~It's easier and
safer to let the computer do algebraic calculations, rather than
to do them by hand. (3)~If the specifications for $z↓1$ and $z↓5$ change,
the formula $\bigl({1\over2}[x↓1,x↓5],b\bigr)$
still gives a reasonable value for~$z↓3$. It's
almost always good to anticipate the need for subsequent modifications.\par
However, the stated formula for $z↓3$ isn't the only reasonable way to
proceed. We could, for example, give two equations
\begindisplay
$x↓3-x↓1=x↓5-x↓3$;\qquad $y↓3=b$;
\enddisplay
the first of these states that the horizontal distance from 1 to 3 is
the same as the horizontal distance from 3 to~5. We'll see later that
\MF\ is able to solve a wide variety of equations.
\ddangerexercise Given $z↓1$, $z↓3$, and $z↓5$ as above, explain how
to define $z↓2$ and~$z↓4$ so that all of the following conditions hold:
\enddanger
\smallskip
\item\bull the line from $z↓2$ to $z↓4$ slopes upward at a $20↑\circ$ angle;
\item\bull the $y$ coordinate of that line's midpoint is 2/3 of the
way from $y↓3$ to $y↓1$;
\item\bull $z↓2$ and $z↓4$ are on the respective lines $z↓1\to z↓3$ and
$z↓3\to z↓5$.
\smallskip\noindent
(If you solve this exercise, you deserve an `{\manual\Az}'.)
\answer The following four equations suffice to define the four
unknown quantities $x↓2$, $y↓2$, $x↓4$, and $y↓4$:
$z↓4-z↓2="whatever"\times"angle"\,20$;
${1\over2}[y↓2,y↓4]={2\over3}[y↓3,y↓1]$;
$z↓2="whatever"[z↓1,z↓3]$;
$z↓4="whatever"[z↓3,z↓5]$. ↑↑"whatever" ↑↑{angle}
\endchapter
Here, where we reach the sphere of mathematics,
we are among processes which seem to some
the most inhuman of all human activities
and the most remote from poetry.
Yet it is here that the artist has the fullest scope for his imagination.
\author HAVELOCK ↑{ELLIS}, {\sl The Dance of Life\/} (1923) % pp 138--139
\bigskip
I haven't kept score, but I would say that
of the two hundred or so books he ↑↑{Wolfe, Nero} reads in a year
not more than five or six get an A.
\author REX ↑{STOUT}, {\sl Plot It Yourself\/\kern-1pt} (1959) % 1st paragraph
\eject
\beginchapter Chapter 3. Curves
Albrecht ↑{D\"urer} and other Renaissance men attempted to establish
mathematical principles of type design, but the letters they came up with
were not especially beautiful. Their methods failed because they
restricted themselves to ``ruler and compass'' constructions, which cannot
adequately express the nuances of good calligraphy. \MF\ gets around this
problem by using more powerful mathematical techniques, which provide the
necessary flexibility without really being too complicated. The purpose of
the present chapter is to explain the simple principles by which a
computer is able to draw ``pleasing'' ↑{curves}.
The basic idea is to start with four points $(z↓1,z↓2,z↓3,z↓4)$ and to
↑↑{four-point method for curves}
construct the three ↑{midpoints} $z↓{12}={1\over2}[z↓1,z↓2]$,
$z↓{23}={1\over2}[z↓2,z↓3]$, $z↓{34}={1\over2}[z↓3,z↓4]$:
\displayfig 3a (5pc)
Then take those three midpoints $(z↓{12},z↓{23},z↓{34})$ and construct
two second-order midpoints $z↓{123}={1\over2}[z↓{12},z↓{23}]$ and
$z↓{234}={1\over2}[z↓{23},z↓{34}]$; finally, construct the third-order
midpoint $z↓{1234}={1\over2}[z↓{123},z↓{234}]$:
\displayfig 3b (5pc)
This point $z↓{1234}$ is one of the points of the curve determined by
$(z↓1,z↓2,z↓3,z↓4)$. To get the remaining points of that curve,
repeat the same construction on $(z↓1,z↓{12},z↓{123},z↓{1234})$ and
on $(z↓{1234},z↓{234},z↓{34},z↓4)$, ad infinitum:
\displayfig 3c (4.5pc)
The process converges quickly, and the preliminary scaffolding
(which appears above the limiting curve in our example) can now be removed.
This limiting curve has the following important properties:
\smallskip
\item\bull It begins at $z↓1$, heading in the direction from $z↓1$ to $z↓2$.
\item\bull It ends at $z↓4$, heading the direction from $z↓3$ to $z↓4$.
\item\bull It stays entirely within the convex hull of $z↓1$, $z↓2$, $z↓3$,
and $z↓4$; i.e., all points of the curve lie ``between'' the defining points.
\danger The curve defined by these recursive rules can be described
algebraically by the remarkably simple formula
\begindisplay
$z(t)\;=\;(1-t)↑3z↓1+3(1-t)↑2t\,z↓2+3(1-t)t↑2z↓3+t↑3z↓4$,
\enddisplay
as the parameter $t$ varies from 0 to 1. This polynomial of degree~3 in~$t$
is called a {\sl ↑{Bernshte{\u\i}n polynomial}}, because Serge\u\i~N.
↑{Bernshte{\u\i}n} introduced such functions in 1912 as part of his
pioneering work on approximation theory. Curves traced out by Bernshte{\u\i}n
polynomials of degree~3 are often called {\sl B\'ezier cubics}, after
Pierre ↑{B\'ezier} who realized their importance for computer-aided design
during the 1960s.
\danger It is interesting to observe that the Bernhte\u\i n polynomial
of degree~1, i.e., the function $z(t)=(1-t)\,z↓1+t\,z↓2$, is precisely the
mediation operator $t[z↓1,z↓2]$ that we discussed in the previous chapter.
Indeed, if the geometric construction we have just seen is changed to
use $t$-of-the-way points instead of midpoints (i.e., if $z↓{12}=
t[z↓1,z↓2]$ and $z↓{23}=t[z↓2,z↓3]$, etc.), then $z↓{1234}$ turns out
to be precisely $z(t)$ in the formula above.
No matter what four points $(z↓1,z↓2,z↓3,z↓4)$ are given, the construction
on the previous page defines a curved line that runs from $z↓1$ to~$z↓4$.
This curve is not always interesting or beautiful; for example, if all
four of the given points lie on a straight line, the entire ``curve''
that they define will also be contained in that same line. We obtain
rather different curves from the same four starting points if we
number the points differently:
\displayfig 3d (8pc)
Some discretion is evidently advisable when the $z$'s are chosen. But the
four-point method is good enough to obtain satisfactory approximations to
any curve we want, provided that we break the desired curve into short
enough segments and give four suitable control points for each segment.
It turns out, in fact, that we can usually get by with only a few segments.
For example, although the four-point method will never produce an exact
circle, it will produce an approximate quarter-circle with less than
0.06\% error; the differences between four such quarter-circles and a
true circle are imperceptible.
All of the curves that \MF\ draws are based on four points, as just
described. But it isn't necessary for a user to specify all of those
points, because the computer is usually able to figure out good values of
$z↓2$ and $z↓3$ by itself. Only the endpoints $z↓1$ and~$z↓4$, through
which the curve is actually supposed to pass, are usually mentioned
explicitly in a \MF\ program.
For example, let's return to the six points that were used to introduce the
ideas of coordinates in Chapter~2. We said `@draw@ $z↓1\to z↓6$' in that
chapter, in order to draw a straight line from point~$z↓1$ to point~$z↓6$;
in general if three or more points are listed instead of two, \MF\ will draw a
↑↑{..} smooth curve through those points. For example, the commands
`@draw@ $z↓4\to z↓1\to z↓2\to z↓6$' and `@draw@ $z↓5\to z↓4\to z↓1
\to z↓3\to z↓6\to z↓5$' will produce the respective results
\displayfig 3e (7.75pc)
(Unlabelled points in these diagrams are ↑{control points} that \MF\ has
supplied automatically so that it can use its four-point scheme to
draw decent curves between each pair of adjacent points on the specified
paths.)
Notice that the curve is not smooth at $z↓5$ in the right-hand example,
because $z↓5$~appears at both ends of that particular path. In order to
get a completely smooth curve that returns to its starting point, you can
say `@draw@ $z↓5\to z↓4\to z↓1\to z↓3\to z↓6\to "cycle"$' instead:
\displayfig 3f (7.25pc)
The word `↑"cycle"\!' at the end of a path refers to the starting point
of that path.
\MF\ believes that this ↑{bean-like shape}
is the nicest way to connect the given points in the given order;
but of course there are many decent curves that satisfy the specifications,
and you may have another one in mind. You can obtain finer control
by giving hints to the machine in various ways. For example, the
bean curve can be ``pulled tighter'' between $z↓1$ and~$z↓3$ if you say
\begindisplay
@draw@ $z↓5\to z↓4\to z↓1\to\tension1.2\to z↓3\to z↓6\to "cycle"$;
\enddisplay
the so-called ↑{tension} between points is normally 1, and an increase
to 1.2 yields
\displayfig 3g (5.75pc)
\danger An unsymmetrical effect can be obtained by increasing the tension
only at point~1 but not at points 3~or~4; the shape
\displayfig 3h (6.5pc)
comes from
%\begindisplay
%@draw@ $z↓5\to z↓4\to\tension1\and1.5\to z↓1\to
% \tension1.5\and1\to z↓3$\cr
%\hskip6em$\to z↓6\to "cycle"$.
%\enddisplay
`@draw@ $z↓5\to z↓4\to\tension1\and1.5\to z↓1\to
\tension1.5\and1\to z↓3\to z↓6\to "cycle"$'.
The effect of tension has been achieved in this example by moving two of
the anonymous control points closer to point~1.
It's also possible to control a curve by telling \MF\ what direction to
travel at some or all of the points. Such directions are given inside
curly braces; for example,
\begindisplay
@draw@ $z↓5\to z↓4\{"left"\}\to z↓1\to z↓3\to z↓6\{"left"\}\to"cycle"$
\enddisplay
says that the curve should be traveling leftward at points 4 and 6. The
resulting curve is perfectly straight from $z↓6$ to~$z↓5$ to~$z↓4$:
\displayfig 3i (5.8pc)
We will see later that `"left"' is an abbreviation for the vector $(-1,0)$,
which stands for one unit of travel in a leftward direction. Any desired
direction can be specified by enclosing a vector in $\{\ldots\}$'s; for
example, the command `@draw@ $z↓4\to z↓2\{z↓3-z↓4\}\to z↓3$' will draw a
curve from $z↓4$ to~$z↓2$ to~$z↓3$ such that the tangent direction at
$z↓2$ is parallel to the line $z↓4\to z↓3$, because $z↓3-z↓4$ is the
vector that represents travel from $z↓4$ to~$z↓3$:
\displayfig 3j (4.7pc)
The same result would have been obtained from a command such as `@draw@
$z↓4\to z↓2 \{10(z↓3-z↓4)\}\to z↓3$', because the vector $10(z↓3-z↓4)$ has
the same direction as $z↓3-z↓4$. \MF\ ignores the magnitudes of vectors
when they are simply being used to specify directions.
\exercise What do you think will be the result of
`@draw@ $z↓4\to z↓2\{z↓4-z↓3\}\to z↓3$', when points $z↓2$, $z↓3$,~$z↓4$
are the same as they have been in the last several examples?
\answer The direction at $z↓2$ is parallel to the line $z↓4\to z↓3$, but
the vector $z↓4-z↓3$ specifies a direction towards $z↓4$, which is
$180↑\circ$ different from the direction $z↓3-z↓4$ that was discussed in
the text. Thus, we have a difficult specification to meet, and \MF\ draws
a pretzel-shaped curve that loops around in a way that's too ugly to show
here. The first part of the path, from $z↓4$ to $z↓2$, is mirror symmetric
about the line~$z1\to z5$ that bisects $z↓4\to z↓2$, so it starts out in a
south-by-southwesterly direction; the second part is mirror symmetric about
the vertical line that bisects $z↓2\to z↓3$, so when the curve ends at~$z↓3$
it's traveling roughly northwest. The moral is: Don't specify a direction
that runs opposite to (i.e., is the negative of) the one you really want.
\exercise Explain how to get \MF\ to draw the wiggly shape
\displayfig 3k (5pc)
in which the curve aims directly at point 2 when it's at point~6, but
directly away from point~2 when it's at point~4. [{\sl Hint:\/} No
tension changes are needed; it's merely necessary to specify directions
at $z↓4$ and~$z↓6$.]
\answer @draw@ $z↓5\to z↓4\{z↓4-z↓2\}\to z↓1\to z↓3\to z↓6\{z↓2-z↓6\}
\to"cycle"$.
\MF\ allows you to change the shape of a curve at its endpoints by
specifying different amounts of ``↑{curl}.'' For example, the two commands
\begindisplay
@draw@ $z↓4\{\curl0\}\to z↓2\{z3-z4\}\to\{\curl0\}\,z↓3$;\cr
@draw@ $z↓4\{\curl2\}\to z↓2\{z3-z4\}\to\{\curl2\}\,z↓3$\cr
\enddisplay
give the respective curves
\displayfig 3l (5pc)
which can be compared to the one shown earlier when no special curl was
requested. \ (The specification `$\curl1$' is assumed at an endpoint
if no explicit curl or tangent direction has been mentioned, just as
`$\tension1$' is implied between points when no tension has
been explicitly given.)
It's possible to get curved lines instead of straight lines even when
only two points are named, if a direction has been prescribed at one or
both of the points. For example,
\begindisplay
@draw@ $z↓4\{z↓2-z↓4\}\to\{"down"\}\,z↓6$\cr
\enddisplay
asks \MF\ for a curve that starts traveling towards $z↓2$ but finishes
in a downward direction:
\displayfig 3m (4pc)
\danger Here are some of the curves that \MF\ draws between two points, when
it is asked to move outward from the left-hand point at an angle of
$60↑\circ$, and to approach the right-hand point at various different angles:
\displayfig 3aa (2.6cm)
This diagram was produced by the \MF\ program ↑↑@for@ ↑↑@step@ ↑↑@until@ ↑↑"cm"
\begindisplay
@for@ $d=0$ @step@ 10 @until@ 120:\cr
\ @draw@ $(0,0)\{"angle"\,60\}\to\{"angle"\,{-d}\}(6"cm",0)$; @endfor@\cr
\enddisplay
the `↑"angle"\!' function specifies a direction measured in degrees
counterclockwise from a horizontal rightward line, hence `$"angle"\,{-d}$'
gives a direction that is $d↑\circ$ below the horizon. The lowest curves
in the illustration correspond to small values of $d$, and the highest
curves correspond to values near $120↑\circ$.
\danger A car that drives along the upper paths in the diagram above
is always turning to the right, but in the lower paths it comes to a
point where it needs to curve left in order to reach its destination.
The place where a path changes its curvature from right to left or
vice versa is called an ``↑{inflection point}.'' \MF\ introduces
inflection points when it seems better to change the curvature than
to make a sharp turn; indeed, when $d$ is negative there is no way to
avoid points of inflection, and the curves for small positive~$d$ ought to
be similar to those obtained when $d$~has small negative values. The program
\begindisplay
@for@ $d=0$ @step@ $-10$ @until@ $-90$:\cr
\ @draw@ $(0,0)\{"angle"\,60\}\to\{"angle"\,{-d}\}(6"cm",0)$; @endfor@\cr
\enddisplay
shows what \MF\ does when $d$ is negative:
\displayfig 3bb (2.8cm)
\danger It is sometimes desirable to avoid points of inflection when $d$ is
positive, and to require the curve to remain inside of the triangle
determined by its initial and final directions. This can be achieved
by insisting that the curve be `↑{bounded}': The program
\begindisplay
@for@ $d=0$ @step@ 10 @until@ 120:\cr
\ @draw@ $(0,0)\{"angle"\,60\}\to\{"angle"\,{-d}\}(6"cm",0)$; @endfor@\cr
\enddisplay
generates the curves
\displayfig 3cc (2.6cm)
which are the same as before except that inflection points do not occur.
A `bounded' specification has no effect when inflection points cannot
be avoided, i.e., when the initial and final directions lie on opposite
sides of the straight line connecting the endpoints.
In this chapter we have seen lots of different ways to get \MF\ to draw
curves. And there's one more way, which subsumes all of the others.
If changes to tensions, curls, angles, and/or boundedness
aren't enough to produce the sort of curve that a person wants, it's
always possible as a last resort to specify all four of the points in the
four-point method. For example, the command
\begindisplay
@draw@ $z↓4\to\controls z↓1\and z↓2\to z↓6$
\enddisplay
will draw the following curve from $z↓4$ to $z↓6$:↑↑{controls}
\displayfig 3n (5pc)
\endchapter
And so I think I have omitted nothing
% Et ainsi ie pense n'auoir rien omis des elemens,
that is necessary to an understanding of curved lines.
% qui sont necessaires pour la connoissance des lignes courbes.
\author REN\'E DESCARTES, {\sl La G\'eom\'etrie\/} (1637) % p369
\bigskip
A second quotation.
\author A SECOND AUTHOR, {\sl A Second Title\/} (1776)
\eject
\beginchapter Chapter 4. Pens
Our examples so far have involved straight lines or curved lines that look
as if they were drawn by a felt-tip ↑{pen}, where the ↑{nib} of that pen
was perfectly round. A mathematical ``line'' has no thickness, so it's
invisible; but when we plot circular dots at each point of an infinitely
thin line, we get a visible line that has constant thickness.
Lines of constant thickness have their uses, but \MF\ also provides
several other kinds of scrivener's tools, and we shall take a look at some
of them in this chapter. We'll see not only that the sizes and shapes of
pen nibs can be varied, but also that characters can be built up in such a
way that the outlines of each stroke are precisely controlled.
\def\kk{\kern2pt } % kidney-bean kern
First let's consider the simplest extensions of what we have seen before.
The letter `{\manual\Aa}' of Chapter~2 and the kidney-↑{bean}
`\kk{\manual\beana}\kk' of Chapter~3 were drawn with circular pen nibs of
diameter $0.4\pt$, where `pt' stands for a printer's point;\footnote*{$
1\,{\rm in}=2.54\,{\rm cm}=72.27\pt$ exactly, as explained in
{\sl The \TeX book}.} $0.4\pt$ is the standard thickness of a ruled line
`$\,\vcenter{\hrule width 2em}\,$' drawn by \TeX. Such a penpoint can be
specified by telling \MF\ to
\begindisplay
\pickup "pencircle" "scaled" $0.4"pt"$;
\enddisplay
\MF\ will use the pen it has most recently picked up ↑↑@pickup@
whenever it is asked to `↑@draw@' anything. A ↑"pencircle" is a
circular pen whose diameter is the width of one pixel. Scaling it
by $0.4"pt"$ will change it to the size that corresponds
to $0.4\pt$ in the output, because ↑"pt" is the number of pixels
in $1\pt$. If the key points $(z↓1,z↓2,z↓3,z↓4,z↓5,z↓6)$ of Chapters 2 and~3
have already been defined, the \MF\ commands
\begindisplay
\pickup "pencircle" "scaled" $0.8"pt"$;\cr
@draw@ $z↓5\to z↓4\to z↓1\to z↓3\to z↓6\to "cycle"$\cr
\enddisplay
will produce a bean shape twice as thick as before: `\kk{\manual\beanb}\kk'
instead of `\kk{\manual\beana}\kk'.
More interesting effects arise when we use non-circular pen nibs. For example,
the command
\begindisplay
\pickup "pencircle" ↑"xscaled" $0.8"pt"$ ↑"yscaled" $0.2"pt"$
\enddisplay
picks up a pen whose tip has the shape of an ellipse, $0.8\pt$ wide and
$0.2\pt$ tall; magnified 10 times, it looks like this:
`$\,\vcenter{\hbox{\manual\niba}}\,$'.
\ (The operation of ``xscaling'' multiplies $x$~coordinates by a specified
amount but leaves $y$~coordinates unchanged, and the operation of
``yscaling'' is similar.) \ Using such a pen, the `\kk{\manual\beana}\kk'
becomes `\kk{\manual\beanc}\kk', and `{\manual\Aa}' becomes `{\manual\Ab}'.
Furthermore,
\begindisplay
\pickup "pencircle" "xscaled" $0.8"pt"$ "yscaled" $0.2"pt"$ ↑"rotated" 30
\enddisplay
takes that ellipse and rotates it $30↑\circ$ counterclockwise, obtaining the nib
`$\vcenter{\hbox{\manual\nibb}}$'; this changes `\kk{\manual\beanc}\kk' into
`\kk{\manual\beand}\kk' and `{\manual\Ab}' into `{\manual\Ac}'. An
enlarged view of the bean shape shows more clearly what is going on:
\displayfig 4a (7pc)
The right-hand example was obtained by eliminating the clause
`"yscaled"~$0.2"pt"$'; this makes the pen almost razor thin, only
one pixel tall before rotation.
\exercise Describe the pen shapes defined by
(a)~"pencircle" "xscaled"~$0.2"pt"$ "yscaled"~$0.8"pt"$;
\ (b)~"pencircle" "scaled"~$0.8"pt"$ "rotated"~30;
\ (c)~"pencircle" "xscaled"~.25 "scaled"~$0.8"pt"$.
\answer (a)~An ellipse $0.8\pt$ tall and $0.2\pt$ wide
(`$\,\vcenter{\hbox{\manual\nibc}}\,$');
\ (b)~A~circle of diameter $0.8\pt$ (rotation doesn't change a circle!);
\ (c)~same as~(a).
\exercise We've seen many examples of `↑@draw@'
used with two or more points. What do you think \MF\ will do
if you ask it to perform the following commands?
\begindisplay
@draw@ $z↓1$;\ @draw@ $z↓2$; \ @draw@ $z↓3$; \ @draw@ $z↓4$;
\ @draw@ $z↓5$; \ @draw@ $z↓6$.
\enddisplay
\answer Six individual points will be drawn, instead of lines or curves.
These points will be drawn with the current pen. However, for technical
reasons explained in Chapter~xx, the @draw@ command does its best work when it
is moving the pen; the pixels you get at the endpoints of curves are
not always what you would expect, especially at low resolutions. It is
usually best to say `↑@filldot@' instead of `@draw@' when you are drawing
only ↑{one point}.
\def\hidecoords(#1,#2){\hbox to 0pt{\hss$\scriptstyle(#1,#2)$\hss}}
\setbox0=\vtop{\kern 42pt
\rightline{\vbox{\hbox to 208\apspix{\hidecoords(0,h)\hfil\hidecoords(w,h)}
\kern3pt
\figbox{4b}{208\apspix}{216\apspix}\vbox
\kern-3pt
\hbox to 208\apspix{\hidecoords(0,0)\hfil\hidecoords(w,0)}}\quad}}
\dp0=0pt
\hangindent-125pt \hangafter4
\indent\strut\vadjust{\box0}%
Let's turn now to the design of a real letter that has already appeared
many times in this manual, namely the `\thinspace{\manual ↑{T}}\thinspace' of
`\MF'. All seven of ↑↑{METAFONT logo} the distinct letters in `\MF' will
be used to illustrate various ideas as we get into the details of the
language; we might as well start with~`\thinspace{\manual T}\thinspace',
because it occurs twice, and (especially) because it's the simplest. An
enlarged version of this letter is shown at the right of this paragraph,
including the locations of its four key points $(z↓1,z↓2,z↓3,z↓4)$ and its
↑{bounding box}. Typesetting systems like \TeX\ are based on the
assumption that each character fits in a rectangular ↑{box}; we shall
discuss boxes in detail later, but for now we will be content simply to
know that such boundaries do exist.\footnote*{Strictly speaking, the
bounding box doesn't strictly have to ``bound'' the black pixels of a
character; for example, the `\thinspace{\manual q}\thinspace' protrudes
slightly below the baseline at point~4, and italic letters frequently
extend rather far to the right of their boxes. However, \TeX\ positions
all characters by lumping boxes together as if they were pieces of metal
type that contain all of the ink.} Numbers $h$ and~$w$ ↑↑"h" ↑↑"w" will
have been computed so that the corners of the box are at positions
$(0,0)$, $(0,h)$, $(w,0)$, and~$(w,h)$ as shown.
\hangindent-125pt
\hangafter\prevgraf \advance\hangafter by -16 % 4+12 (12 lines for the figure)
Each of the letters in `\MF' is drawn with a pen whose nib is an unrotated
ellipse, 90\% as tall as it is wide. In the 10-point size, which is used
for the main text of this book, the pen is $2/3\pt$ wide, so it has
been specified by the command
\begindisplay
\pickup "pencircle" "scaled" $2\over3$"pt" "yscaled" $9\over10$
\enddisplay
or something equivalent to this.
We shall assume that a special value `$o$' has been computed so that the
bottom of the vertical stroke in `\thinspace{\manual T}\thinspace' should
descend exactly $o$~pixels below the baseline; ↑↑"o" this is called the
amount of ``↑{overshoot}.'' Given $h$, $w$, and~$o$, it is a simple matter
to define the four key points and to draw the
`\thinspace{\manual T}\thinspace': ↑↑"top" ↑↑"lft" ↑↑"rt" ↑↑"bot"
\begindisplay
$"top"\,"lft"\,z↓1=(0,h)$; \quad $"top"\,"rt"\,z↓2=(w,h)$;\cr
$"top"\,z↓3=(.5w,h)$; \quad $"bot"\,z↓4=(.5w,-o)$;\cr
@draw@ $z↓1\to z↓2$; \quad @draw@ $z↓3\to z↓4$.\cr
\enddisplay
\danger Sometimes it is easier and/or clearer to define the $x$ and~$y$
↑{coordinates} separately. For example, the key points of
the~`\thinspace{\manual j}\thinspace'
could also be specified thus:
\begindisplay
$"lft"\,x↓1=0$;&$w-x↓2=x↓1$;&$x↓3=x↓4=.5w$;\cr
$"top"\,y↓1=h$;&$"bot"\,y↓4=-o$;&$y↓1=y↓2=y↓3$.\cr
\enddisplay
The equation $w-x↓2=x↓1$ expresses the fact that $x↓2$ is just as far from
the right edge of the bounding box as $x↓1$ is from the left edge.
\danger What exactly does `"top"\!' mean in a \MF\ equation? If the
currently-picked-up pen extends $l$~pixels to the left of its center,
$r$~pixels to the right, $t$~pixels upward and $b$~downward, then
\begindisplay
$"top"\,z=z+(0,t)$,\kern-1em&$"bot"\,z=z-(0,b)$,\kern-1em&
$"lft"\,z=z-(0,l)$,\kern-1em&$"rt"\,z=z+(0,r)$,\cr
\noalign{\vskip\belowdisplayskip
\vbox{\strut
when $z$ is a pair of coordinates. But---as the previous paragraph
shows, if you study it carefully---we also have
\strut}\vskip\abovedisplayskip}
$"top"\,y=y+t$,&$"bot"\,y=y-b$,&
$"lft"\,x=x-l$,&$"rt"\,x=x+r$,\cr
\enddisplay
when $x$ and $y$ are single values instead of coordinate pairs.
You shouldn't apply `"top"\!' or `"bot"\!' to $x$~coordinates,
nor `"lft"\!' or `"rt"\!' to $y$~coordinates.
\dangerexercise True or false: $"top"\,"bot"\,z=z$, whenever $z$
is a pair of coordinates.
\answer True, for all of the pens discussed so far. But false in general,
since we will see later that pens might extend further upward than
downward; i.e., $t$~might be unequal to~$b$ in the equations for
"top" and "bot".
\setbox0=\vtop{\kern -12pt
\rightline{\vbox{\hbox to 288\apspix{\hidecoords(0,h)\hfil\hidecoords(w,h)}
\kern3pt
\figbox{4c}{288\apspix}{216\apspix}\vbox
\kern-3pt
\hbox to 288\apspix{\hidecoords(0,0)\hfil\hidecoords(w,0)}}\quad}}
\dp0=0pt
\begingroup\decreasehsize 165pt
\dangerexercise An enlarged \strut\vadjust{\box0}%
picture of \MF's `{\manual h}' shows that it has five key points. Assuming ↑↑{M}
that special values $s$ and~$yy$ have been precomputed and that the equations
\begindisplay
$x↓1=s$;\quad$y↓3=yy$;\quad$w-x↓5=x↓1$\cr
\enddisplay
have already been given, what further equations and `@draw@' ↑↑{METAFONT
logo} commands will complete the specification of this letter? \ (The
value of~$w$ will be greater for~`\thinspace{\manual h}\thinspace' than it was
for~`\thinspace{\manual j}\thinspace'; it
stands for the pixel width of whatever character is currently being drawn.)
\answer $x↓2=x↓1$; $x↓3={1\over2}[x↓2,x↓4]$; $x↓4=x↓5$; $"bot"\,y↓1=-o$;
$"top"\,y↓2=h+o$; $y↓4=y↓2$; $y↓5=y↓1$; @draw@ $z↓1\to z↓2$;
@draw@ $z↓2\to z↓3$; @draw@ $z↓3\to z↓4$; @draw@ $z↓4\to z↓5$.
We will learn later that the four @draw@ commands can be replaced by
\begindisplay
@draw@ $z↓1\dashto z↓2\dashto z↓3\dashto z↓4\dashto z↓5$;
\enddisplay
in fact, this will make \MF\ run slightly faster. ↑↑{--}
\endgroup % end of the diminished \hsize
\MF's ability to `@draw@' allows it to produce character shapes that are
satisfactory for many applications, but the shapes are inherently limited
by the fact that the simulated pen nib must stay the same through an
entire stroke. Human penpushers are able to get richer effects by
using different amounts of pressure and/or by rotating the pen as they draw.
We can obtain finer control over the characters we draw if we specify
their outlines, instead of working only with key points that lie somewhere
in the middle. In fact, \MF\ works internally with outlines, and the
computer finds it much easier to fill a region with solid black than to
figure out what pixels are blackened by a moving pen. There's a `↑@fill@'
command that does region filling; for example, the solid ↑{bean} shape
\displayfig 4d (7.5pc)
can be obtained from our six famous example points by giving the command
\begindisplay
@fill@ $z↓5\to z↓4\to z↓1\to z↓3\to z↓6\to "cycle"$.
\enddisplay
The region that is filled is essentially what would be cut out by an
infinitely sharp ↑{knife} blade if it traced over the given curve while
cutting a piece of thin film. A @draw@ command needs to add thickness to
its curve, because the result would otherwise be invisible; but a @fill@
command adds no thickness.
The curve in a @fill@ command must end with `↑"cycle"\!', because an
entire region must be filled. It wouldn't make sense to say, e.g.,
`@fill@ $z↓1\to z↓2$'. The cycle being filled shouldn't cross itself,
either; \MF\ would have lots of trouble trying to figure out how to
obey a command like `@fill@ $z↓1\to z↓6\to z↓3\to z↓4\to"cycle"$\!'.
\dangerexercise Chapter 3 discusses the curve $z↓5\to z↓4\to z↓1\to
z↓3\to z↓6\to z↓5$, which isn't smooth at~$z↓5$. Since this curve
doesn't end with `"cycle"\!', you can't use it in a @fill@ command.
But it does define a closed region. How can \MF\ be instructed
to fill that region?
\answer Either say `@fill@ $z↓5\to z↓4\to z↓1\to z↓3\to z↓6\to z↓5\to
"cycle"$\!', or `@fill@ $z↓5\{\curl1\}\to z↓4\to z↓1\to z↓3\to z↓6\to
\{\curl1\}"cycle"$\!'. In the latter case you can omit either one of
the ↑{curl} specifications, but not both.
The black ↑{triangle} `{\manual\char'170}' that appears in the statement of
exercises in this book was drawn with the command
\begindisplay
@fill@ $z↓1\dashto z↓2\dashto z↓3\dashto"cycle"$
\enddisplay
after appropriate corner points $z↓1$, $z↓2$, and $z↓3$ had been specified.
In this case the outline of the region to be filled was specified in terms
of the symbol `$\dashto$' instead of `$\to$'; ↑↑{--}↑↑{..}
this is a convention we haven't discussed before. Each `$\dashto$'
introduces a straight line segment, which is independent of the rest of
↑↑{polygonal path}
the path that it belongs to; thus it is quite different from `$\to$', which
specifies a possibly curved line segment that connects smoothly with neighboring
points and lines of a path. In this case `$\dashto$' was used so that the
triangular region would have straight edges and sharp corners. We might say
informally that `$\to$' means ``Connect the points with a nice curve,''
while `$\dashto$' means ``Connect the points with a straight line.''
\setbox0=\vtop{\kern -9pt
\rightline{\vbox{\hbox to 180\apspix{\hidecoords(0,h)\hfil\hidecoords(w,h)}
\kern3pt
\figbox{4e}{180\apspix}{225\apspix}\vbox
\kern-3pt
\hbox to 180\apspix{\hidecoords(0,0)\hfil\hidecoords(w,0)}}\quad}}
\dp0=0pt
\begingroup\decreasehsize 111pt
\danger \strut\vadjust{\box0}%
The corner points $z↓1$, $z↓2$, and $z↓3$ were defined carefully
so that the triangle would be {\sl↑{equilateral}}, i.e., so that all three
of its sides would have the same length. Since an equilateral triangle
has $60↑\circ$ angles, the following equations did the job:
\begindisplay
$x↓1=x↓2=w-x↓3=s$;\cr
$y↓3=.5h$;\cr
$z↓1-z↓2=(z↓3-z↓2)$ ↑"rotated" 60.\cr
\enddisplay
Here $w$ and $h$ represent the character's width and height, and $s$~is
the distance of the triangle from the left and right edges of the type.
\endgroup % end of the diminished \hsize
\danger The @fill@ command has a companion called ↑@unfill@, which changes
pixels from black to white inside a given region. For example, the solid
bean shape on the previous page can be changed to
\displayfig 4f (7.5pc)
if we say also `@unfill@ ${1\over4}[z↓4,z↓2]\to{3\over4}[z↓4,z↓2]\to"cycle"$;
\ @unfill@ ${1\over4}[z↓6,z↓2]\to{3\over4}[z↓6,z↓2]\to"cycle"$\!'.
\dangerexercise Let $z↓0$ be the point $(.8[x↓1,x↓2],.5[y↓1,y↓4])$,
and introduce six new points by letting $z'↓k=.2[z↓k,z↓0]$ for $k=1,$ 2,
\dots,~6. Explain how to obtain the shape
\displayfig 4g (7.5pc)
in which the interior region is defined by $z'↓1\ldots z'↓6$ instead of
by $z↓1\ldots z↓6$.
The ability to fill between outlines makes it possible to pretend that we
have ↑{broad-edge pens} that change in direction and pressure as they
glide over the paper, if we consider the separate paths traced out by the
pen's left edge and right edge. For example, the stroke
\displayfig 4h (3pc)
can be regarded as drawn by a pen that starts at the left, inclined
at a $30↑\circ$ angle; as the pen moves, it turns gradually until its
↑↑{angle of pen} edge is strictly vertical by the time it reaches the
right end. The pen motion was horizontal at positions 2 and~3. This stroke
was actually obtained by the command
\begindisplay
@fill@ $z↓{1l}\to z↓{2l}\{"right"\}\to\{"right"\}\,z↓{3l}$\cr
$\hskip4em\dashto z↓{3r}\{"left"\}\to\{"left"\}\,z↓{2r}\to z↓{1r}$\cr
$\hskip4em\dashto"cycle"$;
\enddisplay
i.e., \MF\ was asked to fill a region bounded by a ``left path'' from
$z↓{1l}$ to $z↓{2l}$ to $z↓{3l}$, followed by a straight line ↑↑{--}
to~$z↓{3r}$, then a reversed ``right path'' from $z↓{3r}$ to $z↓{2r}$ to
$z↓{1r}$, and finally a straight line back to the starting point~$z↓{1l}$.
Key positions of the ``pen'' are represented in this example by sets of
three points, like $(z↓{1l},z↓1,z↓{1r})$, which stand for the pen's left edge,
its midpoint, and its right edge. The midpoint doesn't actually occur in the
outline, but we'll see examples of its usefulness. The relationships between
such triples of points are established by a `↑"penpos"' command, which states
the breadth of the pen and its angle of inclination at a particular position.
For example, positions 1, 2, and~3 in the stroke above were established
by saying
\begindisplay
$\penpos1(1.2"pt",30)$;&
$\penpos2(1.0"pt",45)$;&
$\penpos3(0.8"pt",90)$;\cr
\enddisplay
this made the pen $1.2\pt$ broad and tipped $30↑\circ$ with respect to
the horizontal at position~1, etc. In general the idea is to specify
\begindisplay
$\penpos k(b,d)$
\enddisplay
where $k$ is the position number or position name, $b$ is the breadth (in
pixels), and $d$~is the angle (in degrees). Pen angles are measured
counterclockwise from the horizontal. Thus an angle of 0 makes the right
edge of the pen exactly $b$~pixels to the right of the left edge; an angle
of 90 makes the right edge exactly $b$~pixels above the left; an angle
of~$-90$ makes it exactly $b$~pixels below. An angle of 45 makes the right
edge $b/{\sqrt2}$ pixels above and $b/{\sqrt2}$ pixels to the right of the
left edge; an angle of~$-45$ makes it $b/{\sqrt2}$ pixels below and
$b/{\sqrt2}$ to the right. When the pen angle is between $90↑\circ$ and
$180↑\circ$, the ``right'' edge actually lies to the left of the ``left''
edge. In terms of ↑{compass directions} on a conventional map, an angle
of~$0↑\circ$ points due East, while $90↑\circ$ points North and $-90↑\circ$
points South. The angle corresponding to Southwest is $-135↑\circ$,
also known as $+225↑\circ$.
\exercise What angle corresponds to the direction North by Northwest?
\answer ${1\over2}\bigl["North",{1\over2}["North","West"]\bigr]=
{1\over2}\bigl[90,{1\over2}[90,180]\bigr]={1\over2}[90,135]=112.5$.
\begingroup \decreasehsize 9pc
\exercise \xdef\circlex{4.\number\exno}%
\rightfig 4i (7pc x 7pc) ↑20pt
What are the pen angles at positions 1, 2, 3, and~4 in
the circular shape shown here? [{\sl Hint:\/} Each angle is a multiple
of $30↑\circ$. Note that $z↓{3r}$ lies to the left of $z↓{3l}$.]
\answer $30↑\circ$, $60↑\circ$, $210↑\circ$, and $240↑\circ$. Since it's
possible to add or subtract $360↑\circ$ without changing the meaning,
the answers $-330↑\circ$, $-300↑\circ$, $-150↑\circ$, and $-120↑\circ$
are also correct.
\exercise What are the coordinates of $z↓{1l}$ and $z↓{1r}$ after the
command `$\penpos1(10,-90)$', if $z↓1=(25,25)$?
\answer $z↓{1l}=(25,30)$, $z↓{1r}=(25,20)$.
\endgroup % end of the diminished \hsize
\danger The statement `$\penpos k(b,d)$' is simply an abbreviation for
two equations, `$z↓k={1\over2}[z↓{kl},z↓{kr}]$' and
`$z↓{kr}=z↓{kl}+(b,0)$ ↑"rotated"~$d\,$'. You might want to use other
equations to define the relationship between $z↓{kl}$, $z↓k$, and
$z↓{kr}$, instead of giving a "penpos" command, if an alternative
formulation turns out to be more convenient.
After `"penpos"' has specified the relation between three points, we still
don't know exactly where they are; we only know their positions relative
to each other. Another equation or two is needed in order to fix the
horizontal and vertical locations of each triple. For example, the three
"penpos" commands that led to the pen stroke on the previous page were
accompanied by the equations
\begindisplay
$z↓1=(0,2"pt")$;&$z↓2=(4"pt",0)$;&$x↓3=9"pt"$;&$y↓{3l}=y↓{2r}$;
\enddisplay
these made the information complete. There should be one $x$~equation and
one $y$~equation for each position; or you can use a $z$~equation, which
defines both $x$ and~$y$ simultaneously.
It's a nuisance to write long-winded @fill@ commands when broad-edge
pens are being simulated in this way, so \MF\ provides a convenient
abbreviation: You can write simply
\begindisplay
↑"penstroke"$(1,2,3)$
\enddisplay
instead of the command `\thinspace@fill@ $z↓{1l}\to
z↓{2l}\{"right"\}\to\{"right"\}\,z↓{3l} \dashto
z↓{3r}\{"left"\}\to\{"left"\}\,z↓{2r}\to z↓{1r}\dashto"cycle"$' that was
stated earlier. How does "penstroke" know in this case that it should be
filling an outline that travels "right" at positions $z↓{2l}$
and~$z↓{3l}$, "left" at positions $z↓{3r}$ and~$z↓{2r}$? Good question. If
you want to specify particular directions at certain positions, you can
say, e.g.,
\begindisplay
$dz↓2=dz↓3="right"$;
\enddisplay
↑↑{dz} this makes the simulated pen travel horizontally to the right at
positions 2 and~3. In general, $dz↓k$ stands for a specified direction
at pen position~$k$; `"penstroke"' will use this direction at $z↓{kl}$
and~$z↓{kr}$ if $dz↓k$ has previously been given a value, but it will
let \MF\ choose the directions if $dz↓k$ has not been defined. \ (Actually
the reverse direction is used at $z↓{kr}$, because the right path is
traversed backwards.)
\danger You can also define $dz↓{kl}$ and $dz↓{kr}$ separately,
if you want independent tangent directions at $z↓{kl}$ and $z↓{kr}$.
\danger The "penstroke" abbreviation can be used to draw cyclic paths
as well as ordinary ones. For example, the circle in exercise \circlex\
was created by saying simply `$"penstroke"(1,2,3,4,"cycle")$'. If no
directions have been specified, this type of penstroke essentially
expands into
\begindisplay
@fill@ $z↓{1r}\to z↓{2r}\to z↓{3r}\to z↓{4r}\to"cycle"$;\cr
@unfill@ $z↓{1l}\to z↓{2l}\to z↓{3l}\to z↓{4l}\to"cycle"$;\cr
\enddisplay
or the operations `@fill@' and `@unfill@' are reversed, if points
$(z↓{1r},z↓{2r}, z↓{3r},z↓{4r})$ are on the inside and
$(z↓{1l},z↓{2l},z↓{3l},z↓{4l})$ are on the outside.
\dangerexercise The circle of exercise \circlex\ was actually drawn with
directions specified; the edges of the curve were forced to be vertical at
positions 1 and~3, horizontal at 2 and~4. What values of $dz↓1$, $dz↓2$,
$dz↓3$, and $dz↓4$ were used? What were the corresponding @fill@
and~@unfill@ commands that resulted from $"penstroke"(1,2,3,4,"cycle")$ in
that case?
\answer $dz↓1="up"$; $dz↓2="left"$; $dz↓3="down"$; $dz↓4="right"$.
These directions caused "penstroke" to expand into
\begindisplay
@fill@ $z↓{1r}\{"up"\}\to z↓{2r}\{"left"\}\to z↓{3r}\{"down"\}
\to z↓{4r}\{"right"\}\to"cycle"$;\cr
@unfill@ $z↓{1l}\{"up"\}\to z↓{2l}\{"left"\}\to z↓{3l}\{"down"\}
\to z↓{4l}\{"right"\}\to"cycle"$.\cr
\enddisplay
\setbox0=\vtop{\kern 21pt
\rightline{\vbox{\hbox to 216\apspix{\hidecoords(0,h)\hfil\hidecoords(w,h)}
\kern6pt
\figbox{4j}{216\apspix}{252\apspix}\vbox
\kern-3pt
\hbox to 216\apspix{\hidecoords(0,0)\hfil\hidecoords(w,0)}}\qquad}}
\dp0=0pt
\hangindent-147pt \hangafter2
\indent\strut\vadjust{\box0}%
Now let's design another letter ↑{T}, based on this new sort of pen, in order
to get further experience. The enlarged character at the right has six key
positions; two of these (positions 2 and~4) share a common midpoint, at the
junction between strokes. The top stroke of a~T is called the {\sl bar},
and the bottom stroke is called the {\sl stem}.
\hangindent-147pt
\hangafter\prevgraf \advance\hangafter by -16 % 2+14 (14 lines for the figure)
As before, we shall assume that two variables $h$ and~$w$ have been set up
to give the height and width of the character, in pixels. We shall also
assume that two other parameters are available: "thin", which tells
the breadth of the pen in the top stroke, and "thick", which governs the
breadth at the bottom. Once we have a suitable program written we can
try different possibilities for "thin" and "thick" until we find what
goes best with other letters.
Since the program is somewhat technical, it should be skimmed on first reading.
It begins with "penpos" statements for the upper bar; these are easy,
except that they involve something that hasn't been explained yet. A
special instruction is used to make the pen ↑{taper} inward at position~2:
\begindisplay
$\penpos1("thin",75)$;\cr
$\penpos2("thin",72)$; \ $\pentaper2(.4,.6)$;\cr
$\penpos3("thin",70)$.\cr
\enddisplay
The statement `$\pentaper2(.4,.6)$' moves point $z↓{2l}$ up $4\over10$ of
the way towards~$z↓2$ from where it was before tapering; similarly,
$z↓{2r}$ is moved $6\over10$ of the way towards the original midpoint.
This makes
the pen somewhat thinner than "thin" at position~2. \ (In fact, it's
exactly half as broad there now as it was before tapering, since we took
$4\over10$ from one half and $6\over10$ from the other.)
The next job is to place positions 1, 2, and 3 on the raster by giving three
$x$~equations and three $y$~equations:
\begindisplay
$x↓{1l}=0$; \ $x↓2=.5w$; \ $x↓3=w$;\cr
$y↓1=y↓{3l}$; \ $y↓2=.5[y↓1,y↓3]$; \ $.2[y↓{2r},y↓{3r}]=h$.\cr
\enddisplay
These $x$ equations are straightforward and require no comment, but the
$y$~equations are somewhat interesting. First, `$y↓1=y↓{3l}$' means that
the left or lower edge of the pen at position~3 is to be at the same height
as the midpoint at position~1; this makes position~3 a bit higher.
Second, `$y↓2=.5[y↓1,y↓3]$' puts $y↓2$ smack in the middle between $y↓1$
and~$y↓3$. Then `$.2[y↓{2r},y↓{3r}]=h$' says that the top of the bounding box
should occur $2\over10$ of the way from position~2 to position~3. With
these equations in addition to the "penpos" specifications, \MF\ has enough
information to determine all of the coordinates $x↓{1l}$, $x↓1$, $x↓{1r}$,
$x↓{2l}$, $x↓2$, $x↓{2r}$, $x↓{3l}$, $x↓3$, $x↓{3r}$, $y↓{1l}$, $y↓1$,
$y↓{1r}$, $y↓{2l}$, $y↓2$, $y↓{2r}$, $y↓{3l}$, $y↓3$, and~$y↓{3r}$.
A similar approach sets up the lower stroke. We want the thick pen to fall
inside the thin stroke at position~4, so we set the angle to $"argd"(z↓3-z↓1)$,
↑↑"argd" which is the angle of the direction vector from $z↓1$ to~$z↓3$.
\begindisplay
$\penpos4("thick","argd"(z↓3-z↓1))$; \ $\pentaper4(.25,.1)$;\cr
$\penpos5("thick",20)$; \ $\pentaper5(.4,0)$;\cr
$\penpos6("thick",10)$;\cr
$z↓2=z↓4$;\cr
$x↓{5r}=x↓{4r}$; \ $x↓6=x↓5$;\cr
$y↓5={2\over3}h$; \ $y↓6=0$.\cr
\enddisplay
It's possible, of course, to play with these equations and get different
positions by varying the angles, amounts of taper, and so on.
Finally the strokes are drawn by saying
\begindisplay
$"penstroke"(1,2,3)$;\cr
$dz↓5="down"$;\cr
$"penstroke"(4,5,6)$.\cr
\enddisplay
That's all it takes to make instant `{\manual\IOT}'.
\danger In general, the phrase `$\pentaper k(a,b)$' is shorthand for four
assignment statements, `$x↓{kl}:=a[x↓{kl},x↓k]$; $y↓{kl}:=a[y↓{kl},y↓k]$;
$x↓{kr}:=b[x↓{kr},x↓k]$; $y↓{kr}:=b[y↓{kr},y↓k]$'. Equations can usually
be given in any order, but `$:=$' ↑↑{:=} changes the meaning of values;
hence the ordering of statements can be significant when tapering is used.
For example, if the equation `$x↓{5r}=x↓{4r}$' had been given before
`$\pentaper4(.25,.1)$', instead of after~it, the value of $x↓{5r}$ would have
been set equal to the value of $x↓{4r}$ {\sl before\/} tapering, so the
final value of $x↓{5r}$ would have been greater than the final value
of~$x↓{4r}$. We shall study the differences between `$:=$' and~`$=$' in a
later chapter.
\danger It is important to note that these simulated pens
have a serious limitation compared to the real pens that calligraphers
use: The left and right edges of a "penpos"-made pen must never cross,
hence it is necessary to turn the pen when going around a curve.
Consider, for example the following two curves:
\displayfig 4k (6pc)
The left-hand circle was drawn with a broad-edge pen of fixed breadth,
held at a fixed angle; consequently the left edge of the pen was responsible
for the outer boundary on the left, but the inner boundary on the right.
\ (This curve was produced by saying `\pickup "pencircle" "xscaled"~0.8"pt"
"rotated"~25; @draw@ $z↓1\to z↓2\to"cycle"$'.) \ The right-hand shape
was produced by `$\penpos1(0.8"pt",25)$;
$\penpos2(0.8"pt",25)$; $"penstroke"(1,2,cycle)$'; important chunks
of the shape are missing at the crossover points, because they don't
lie on either of the circles $z↓{1l}\to z↓{2l}\to"cycle"$ or
$z↓{1r}\to z↓{2r}\to"cycle"$.
\danger To conclude this chapter we shall improve the ↑{hex} character
{\manual\hexb} of Chapter~2, which is too dark in the middle because it has
been drawn with a pen of uniform thickness. The main trouble with unvarying
pens is that they tend to produce black blotches where two strokes join,
unless the pens are comparatively thin or unless the joins are nearly
perpendicular. We want to thin out the lines at the center just enough
to cure the darkness problem, without destroying the illusion that the lines
still seem (at first glance) to have uniform thickness.
\setbox0=\vtop{\kern 80pt
\rightline{\vbox{\hbox to 200\apspix{\hidecoords(0,h)\hfil\hidecoords(w,h)}
\kern3pt
\figbox{4l}{200\apspix}{100\apspix}\vbox
\kern-3pt
\hbox to 200\apspix{\hidecoords(0,0)\hfil\hidecoords(w,0)}}\qquad}}
\dp0=0pt
\danger \strut\vadjust{\box0}%
It isn't difficult to produce `\thinspace
{\manual\hexe\hexe\hexe\hexe\hexe\hexe\hexe\hexe\hexe\hexe}\thinspace'
instead of `\thinspace
{\manual\hexb\hexb\hexb\hexb\hexb\hexb\hexb\hexb\hexb\hexb}\thinspace'
when we work with dynamically varying pens as follows:
\begindisplay
$"top"\,z↓1=(0,h)$; $"top"\,z↓2=(.5w,h)$; $"top"\,z↓3=(w,h)$;\cr
$"bot"\,z↓4=(0,0)$; $"bot"\,z↓5=(.5w,0)$; $"bot"\,z↓6=(w,0)$;\cr
$z↓{1'}=.25[z↓1,z↓6]$; $z↓{6'}=.75[z↓1,z↓6]$;\cr
$d↓1:="argd"(z↓6-z↓1)+90$;\cr
$z↓{3'}=.25[z↓3,z↓4]$; $z↓{4'}=.75[z↓3,z↓4]$;\cr
$d↓3:="argd"(z↓4-z↓3)+90$;\cr
$z↓7=z↓8=.5[z↓1,z↓6]$;\cr
$\penpos{1'}(b,d↓1)$; $\penpos{6'}(b,d↓1)$;\cr
$\penpos7(.6b,d↓1)$;\cr
$\penpos{3'}(b,d↓3)$; $\penpos{4'}(b,d↓3)$;\cr
$\penpos8(.6b,d↓3)$;\cr
$dz↓{1'}=dz↓{6'}=z↓{6'}-z↓{1'}$;\cr
$dz↓{3'}=dz↓{4'}=z↓{4'}-z↓{3'}$;\cr
@draw@ $z↓1\to z↓{1'}$; $"penstroke"(1',7,6')$; @draw@ $z↓{6'}\to z↓6$;\cr
@draw@ $z↓2\to z↓5$;\cr
@draw@ $z↓3\to z↓{3'}$; $"penstroke"(3',8,4')$; @draw@ $z↓{4'}\to z↓4$.\cr
\enddisplay
Here $b$ is the diameter of the pen at the terminal points;
`↑"argd"' computes the direction angle of a given vector.
Adding $90↑\circ$ to a direction angle gives a ↑{perpendicular}
direction (see the definitions of $d↓1$ and~$d↓3$).
It isn't necessary to take anything off of the vertical stroke $z↓2\to z↓5$,
because the two diagonal strokes fill more than the width of the vertical
stroke at the point where they intersect.
\setbox0=\vtop{\kern -30pt
\rightline{\vbox{\hbox to 200\apspix{\hidecoords(0,h)\hfil\hidecoords(w,h)}
\kern6pt
\figbox{4m}{200\apspix}{100\apspix}\vbox
\kern0pt
\hbox to 200\apspix{\hidecoords(0,0)\hfil\hidecoords(w,0)}}\quad}}
\dp0=0pt
\begingroup \decreasehsize 125pt
\dangerexercise \strut\vadjust{\box0}%
Modify the hex character so that its ends are cut
sharply and confined to the bounding box, as shown.
\answer We use angles ↑{perpendicular} to $(w,h)$ and $(w,-h)$ at the
diagonal endpoints:
\begindisplay
$x↓{1l}=x↓{4l}=0$; \ $x↓2=x↓5=.5w$; \ $x↓{3r}=x↓{6r}=w$;\cr
$y↓{1r}=y↓2=y↓{3l}=h$; \ $y↓{4r}=y↓5=y↓{6l}=0$;\cr
$z↓{1'}=.25[z↓1,z↓6]$; \ $z↓{6'}=.75[z↓1,z↓6]$; \ $d↓1:="argd"(w,-h)+90$;\cr
$z↓{3'}=.25[z↓3,z↓4]$; \ $z↓{4'}=.75[z↓3,z↓4]$; \ $d↓3:="argd"(-w,-h)+90$;\cr
$z↓7=z↓8=.5[z↓1,z↓6]$;\cr
$\penpos1(b,d↓1)$; \ $\penpos6(b,d↓1)$;\cr
$\penpos{1'}(b,d↓1)$; \ $\penpos{6'}(b,d↓1)$; \
$\penpos7(.6b,d↓1)$;\cr
$\penpos3(b,d↓3)$; \ $\penpos4(b,d↓3)$;\cr
$\penpos{3'}(b,d↓3)$; \ $\penpos{4'}(b,d↓3)$; \
$\penpos8(.6b,d↓3)$;\cr
$dz↓{1'}=dz↓{6'}=z↓{6'}-z↓{1'}$; \ $dz↓{3'}=dz↓{4'}=z↓{4'}-z↓{3'}$;\cr
$"penstroke"(1,1',7,6',6)$;\cr
$\penpos2(b,0)$; \ $\penpos5(b,0)$; \ $"penstroke"(2,5)$;\cr
$"penstroke"(3,3',8,4',4)$.\cr
\enddisplay
\endgroup % end of the diminished \hsize
\endchapter
It is very important that the nib be cut ``sharp,''
and as often as its edge wears blunt it must be resharpened.
It is impossible to make ``clean cut'' strokes with a blunt pen.
\author EDWARD ↑{JOHNSTON}, {\sl Writing \& Illuminating, %
\& Lettering\/} (1906)
\bigskip
I might compare the high-speed computing machine
to a remarkably large and awkward pencil
which takes a long time to sharpen and
cannot be held in the fingers in the usual manner so that it
gives the illusion of responding to my thoughts,
but is fitted with a rather delicate engine
and will write like a mad thing
provided I am willing to let it dictate pretty much
the subjects on which it writes.
\author R. H. ↑{BRUCK}, {\sl Computational Aspects of Certain
Combinatorial Problems\/} (1956) % AMS Symp Appl Math 6, p31
\eject
\beginchapter Chapter 5. Running\\\MF
It's high time now for you to stop reading and to start playing with the
computer, since \MF\ is an interactive system that is best learned by
trial and error. \ (In fact, one of the nicest things about computer graphics
is that errors are often more interesting and more fun than ``successes.'')
You probably will have to ask somebody how to deal with the idiosyncrasies
of your particular version of the system, even though \MF\ itself works in
essentially the same way on all machines; different computer terminals and
different hardcopy devices make it necessary to have somewhat different
interfaces. In~this chapter we shall assume that you have a computer
terminal with a reasonably high-resolution graphics display; that you have
access to a (possibly low-resolution) output device; and that you can
rather easily get that device to work with newly created fonts.
OK, are you ready to run the program? First you need to log in, of course;
then start \MF, which is usually called ↑|mf| for short. Once you've figured
out how to do it, you'll be welcomed by a message something like
$$\def\\{{\rm\ }} % take a wee bit off of the \tt spaces
\vtop{\line{\indent \tt
This\\is\\METAFONT,\\Version\\1.0\\(preloaded\\base=plain 84.11.8)}
\leftline{\indent \tt **}}$$
The `↑|**|' is \MF's way of asking you for an input file name.
% Incidentally, 84.11.8 was Hermann's 66th birthday.
Now type `|\relax|'---that's ↑{backslash}, |r|, |e|, |l|, |a|, |x|---and
hit ↑\<return> (or~whatever stands for ``end-of-line'' on your keyboard).
\MF\ is all geared up for action, ready to make a big font; but you're
saying that it's all right to take things easy, since this is going to
be a real simple run. The backslash means that \MF\ should not read a file,
it should get instructions from the keyboard; the `↑|relax|' means
``do nothing.''
The machine will respond by typing a single asterisk: `↑|*|'. This means
it's ready to accept instructions (not the name of a file). Type the
following, just for fun:
\begintt
filldot (35,70); showit;
\endtt
and \<return>---don't forget to type the semicolons along with the other
stuff. A more-or-less circular dot, 14~pixels in diameter, should now
appear on your screen! And you should also be prompted with another asterisk.
Type
\begintt
filldot (65,70); showit;
\endtt
and \<return>, to get another dot. \ (Henceforth we won't keep mentioning
the necessity of \<return>ing after each line of keyboard input.) \ Finally,
type
\begintt
draw (20,40)..(50,25)..(80,40); showit; shipit; end.
\endtt
This draws a curve through three given points, displays the result,
↑↑|showit| ↑↑|shipit| ↑↑|end|
ships it to an output file, and stops. \MF\ should respond with `|[0]|',
meaning that it has shipped out a character whose number is zero, in the
``font'' just made; and it should also tell you that it has created
an output file called `|mfput.gf|'. \ (The name ↑|mfput| is used when
you haven't specified any better name in response to the ↑|**| at the
beginning. The suffix ↑|gf| stands for ``↑{generic font}''; the data in
|mfput.gf| can be converted into fonts suitable for a
wide assortment of typographical output devices, but it doesn't
match the font file conventions of any name-brand manufacturer,
so we call it generic.)
This particular file |mfput.gf| won't make a very interesting font,
because it contains only one character, and because it probably doesn't
have the correct resolution for your output device. However, it does
have the right resolution for hardcopy proofs of characters; your next
step therefore should be to convert the data of |mfput.gf| into a
picture, suitable for framing. There should be a program called
↑|GFtoDVI| on your computer. Apply it to |mfput.gf|, thereby
obtaining a file called |mfput.dvi| ↑↑|dvi| that can be printed.
Your friendly local computer hackers will tell you how to run
|GFtoDVI| and how to print |mfput.dvi|; then you'll have a marvelous
souvenir of your very first encounter with \MF.
\smallskip
Once you have made a complete test run as just described, you will
know how to get through the whole cycle, so you'll be ready to tackle
a more complex project. Our next experiment will therefore be
to work from a file, instead of typing the input online.
Use your favorite text editor to create a file called |io.mf| that
contains the following 23 lines of text (no more, no less):
$$\halign{\hbox to\parindent{\hfil\sevenrm#\ \ }\hfil\cr
1&|mode_setup;|\cr\noalign{↑↑"mode\_setup"}
2&| em#:=10pt#; cap#:=7pt#;|\cr
3&| thin#:=1/3pt#; thick#:=5/6pt#;|\cr
4&| o#:=1/5pt#;|\cr
5&|define_pixels(em,cap);|\cr
6&|define_blacker_pixels(thin,thick);|\cr
7&|define_corrected_pixels(o);|\cr
8&| curve_sidebar=round 1/18em;|\cr
9&|beginchar("O",0.8em#,cap#,0); "The letter O";|\cr
10&| penpos1(thick,10); penpos2(.1[thin,thick],90-10);|\cr
11&| penpos3(thick,180+10); penpos4(thin,270-10);|\cr
12&| x1l=w-x3l=curve_sidebar; x2=x4=.5w;|\cr
13&| y1=.49h; y2l=-o; y3=.51h; y4l=h+o;|\cr
14&| dz1=down; dz2=right; dz3=up; dz4=left;|\cr
15&| penstroke(1,2,3,4,cycle);|\cr
16&| penlabels(1,2,3,4); endchar;|\cr
17&|def test_I(expr code,trial_stem,trial_width) =|\cr
18&| stem#:=trial_stem*pt#; define_blacker_pixels(stem);|\cr
19&| beginchar(code,trial_width*em#,cap#,0); "The letter I";|\cr
20&| penpos1(stem,15); penpos2(stem,12); penpos3(stem,10);|\cr
21&| x1=x2=x3=.5w; y1=h; y2=.55h; y3=0;|\cr
22&| pentaper2(.25,.1); dz2=down; penstroke(1,2,3);|\cr
23&| penlabels(1,2,3); endchar; enddef;|\cr}$$
(But don't type the numbers at the left of these lines; they're
only for reference.)
This example file is dedicated to ↑{Io}, the Greek goddess of input
and output. It's a trifle long, but you'll be able to get worthwhile
experience by typing it; so go ahead and type it now. For your own
good. And think about what you're typing, as you go; the example
introduces several important features of \MF\ that you can learn
as you're creating the file.
Here's a brief explanation of what you've just typed: Line~1 contains a
command that usually appears near the beginning of every \MF\ file;
it tells the computer to get ready to work in whatever ``mode'' is
currently desired. \ (A file like |io.mf| can be used to generate
proofsheets as well as to make fonts for a variety of devices at a
variety of magnifications, and `"mode\_setup"' is what adapts \MF\
to the task at hand.) \ Lines 2--8 define parameters that will be used
to draw the letters in the font. Lines 9--16 give a complete program
for the letter `O'; and lines 17--23 give a program that will draw
the letter~`I' in a number of related ways.
It all looks pretty frightening at first glance, but a closer look
shows that Io is not so mysterious once we penetrate her disguise.
Let's spend a few minutes studying the file in more detail.
Lines 2--4 define dimensions that are independent of the mode;
the `|#|' ↑↑{sharpsign} signs are meant to imply ``true'' ↑{units of measure},
which remain the same whether we are making a font at high or low
resolution. For example, one `|pt#|' is a true printer's point, one
72.27th of an inch. This is quite different from the `↑"pt"' we have
discussed in previous chapters, because `"pt"' is the number of pixels that
happen to correspond to a printer's point when the current resolution
is taken into account. The value of `|pt#|' never changes, but
"mode\_setup" establishes the appropriate value of `"pt"'.
The ↑{assignments} `|em#:=10pt#|' and `|cap#:=7pt#|' in line~2 mean that
the Io font has two parameters, called "em" and "cap", whose mode-independent
values are 10 and~7 points, respectively. The statement ↑↑"define\_pixels"
`|define_pixels(em,cap)|' on line~5 converts these values into pixel
units. For example, if we are working at the comparatively low resolution
of 3~pixels per~pt, the values of "em" and "cap" after the computer has
performed the instructions on line~5 will be $"em"=30$ and $"cap"=21$.
\ (We will see later that the widths of characters in this font are
expressed in terms of ems, and that "cap" is the height of the capital
letters. A change to line~2 will therefore affect the widths and/or heights
of all the letters.)
Similarly, the Io font has parameters called "thin" and "thick", defined
on line~3 and converted to pixel units in line~6. These are used to control
the breadth of a simulated pen when it draws the letter~O. Experience has
shown that \MF\ produces better results on certain output devices if
pixel-oriented pens are made slightly broader than the true dimensions would
imply, because black pixels sometimes tend to ``burn off'' in the process
of printing. The command on line~6, `|define_blacker_pixels|',
↑↑"define\_blacker\_pixels" adds a correction based on the device for which
the font is being prepared. For example, if the resolution is 3~pixels
per point, the value of "thin" when converted from true units to pixels
by "define\_pixels" would be~1, but "define\_blacker\_pixels" might set
"thin" to a value closer to~2.
The `|o|' parameter ↑↑"o" on line 4 represents the amount by which curves will
↑{overshoot} their boundaries. This is converted to pixels in yet another
way on line~7, so as to avoid yet another problem that arises in low-resolution
printing. The author apologizes for letting such real-world considerations
intrude into a textbook example; let's not get bogged down in fussy details
now, since these refinements will be explained in Chapter~xx after we have
mastered the basics. For now, the important point is simply that a typeface
design usually involves parameters that represent physical lengths. The
true, ``sharped'' forms of these parameters need to be converted to
``unsharped'' pixel-oriented quantities, and best results are obtained when
such conversions are done carefully. After \MF\ has obeyed line~7 of the
example, the pixel-oriented parameters "em", "cap", "thin", "thick",
and~"o" are ready to be used as we draw letters of the font.
Line 8 defines a quantity called "curve\_sidebar" ↑↑{sidebar} that will
measure the distance of the left and right edges of the `O' from the
bounding box. It is computed by ↑{rounding} ${1\over18}"em"$ to the nearest
integer number of pixels. For example, if $"em"=30$ then ${30\over18}=
{5\over3}$ yields the rounded value $"curve\_sidebar"=2$; there will be
two all-white columns of pixels at the left and right of the `O',
when we work at this particular resolution.
Before we go any further, we ought to discuss the strange collection
of words and pseudo-words in the file |io.mf|. Which of the terms
`|mode_setup|', `|em|', `|curve_sidebar|' and so forth are part of
the \MF\ language, and which of them are made up specifically for
the Io example? Well, it turns out that almost nothing in this
example is written in the pure \MF\ language that the computer understands!
\MF\ is really a low-level language that has been designed to allow easy
adaptation to many different styles of programming, and |io.mf|
illustrates just one of countless ways to use it. Most of the terms
in |io.mf| are conventions of ``↑{plain} \MF\!,'' which is a collection
of subroutines found in Appendix~B. \MF's primitive capabilities are
not meant to be used directly, because that would force a particular style
on all users. A ``base file'' is generally loaded into the computer
at the beginning of a run, so that a standard set of convention is
readily available. \MF's welcoming message, quoted at the
beginning of this chapter, says `|preloaded| |base=plain|'; it
means that the primitive \MF\ language has been extended to include the
features of the plain base file. This book is not only about \MF; it also
explains how to use the conventions of \MF's plain base. Similarly, {\sl
The \TeX book\/} describes a standard extension of \TeX\ called ``plain
\TeX\ format''; ↑↑{TeX} the ``plain'' extensions of \TeX\ and \MF\ are
completely analogous to each other.
The notions of "mode\_setup", "define\_pixels", "beginchar", "penpos",
"penstroke", "dz", and many other things found in |io.mf| are aspects
of plain \MF\ but they are not hardwired into \MF\ itself. Appendix~B
defines all of these things, as well as the relations between ``sharped''
and ``unsharped'' variables. Even the fact that $z↓1$ stands for
$(x↓1,y↓1)$ is defined in Appendix~B; \MF\ does not have this built~in.
You are free to define even fancier bases as you gain more experience,
but the plain base is a suitable starting point for a novice.
\danger If you have important applications that make use of a different
base file, it's possible to create a version of \MF\ that has any desired
base preloaded. Such a program is generally called by a special name,
since the nickname `↑|mf|' is reserved for the version that includes the
standard plain base assumed in this book. For example, the author has made
a special version called `↑|cmmf|' just for the ↑{Computer Modern} typefaces
he has been developing, so that the Computer Modern base file does not
have to be loaded each time he makes a new experiment.
\danger There's a simple way to change the base file from the one that has
been preloaded: If the first character you type in response to `↑|**|' is
an ↑{ampersand} (\thinspace`|&|'\thinspace), \MF\ will replace its memory
with a specified base file before proceeding. If, for example, there is a
base file called `|cm.base|' but not a special program called `|cmmf|',
you can substitute the Computer Modern base for the plain base in |mf| by
typing `|&cm|' at the very beginning of a run. If you are working with a
program that doesn't have the plain base preloaded, the first experiment
in this chapter won't work as described, but you can do it by starting
with `|&plain \relax|' instead of just `|\relax|'. These conventions are
exactly the same as those of \TeX.
Our Ionian example uses the following words that are not part of plain
\MF: "em", "cap", "thin", "thick", "o", "curve\_sidebar", "test\_I", "code",
"trial\_stem", "trial\_width", and "stem". If you change these to some other
words or symbols---for example, if you replace `|thin|' and `|thick|' by
`|t|' and `|T|' respectively, in lines 3, 6, 10, and~11---the results will
be unchanged, unless your substitutions just happen to clash with something
that plain \MF\ has already pre\"empted. In general, the best policy is to
choose descriptive terms for the quantities in your programs, since they
are not likely to conflict with reserved pseudo-words like "penpos" and
"endchar".
We have already noted that lines 9--16 of the file represent a program
for the letter `O'. The main part of this program, in lines 10--15,
uses the ideas of Chapter~4, but we haven't seen the stuff in lines 9
and~16 before. Plain \MF\ makes it convenient to define letters by starting
each one with
\begindisplay
$"beginchar"($\<code>, \<width>, \<height>, \<depth>);↑↑"beginchar"
\enddisplay
here \<code> is either a quoted character like |"O"| or a number that
represents the character's position in the final font. The other three
quantities \<width>, \<height>, and \<depth> say how big the ↑{bounding box}
is, so that typesetting systems like \TeX\ will be able to use the character.
These three dimensions must be given in device-independent units, i.e.,
in ``↑{sharped}'' form.
\exercise What are the height and width of the bounding box described
in the "beginchar" command on line~9 of |io.mf|, given the parameter
values defined on line~2? Give your answer in terms of printer's points.
\answer The width is |0.8em#|, and an |em#| is 10 true points, so the
box will be exactly $8\pt$ wide in device-independent units. The
height will be $7\pt$. \ (And the depth below the baseline will be $0\pt$.)
Each "beginchar" operation assigns values to special variables called
$w$, $h$, and~$d$, ↑↑"w" ↑↑"h" ↑↑"d" which represent the respective
width, height, and depth of the current character's bounding box,
↑{rounded} to the nearest integer number of pixels. Our example file
uses $w$ and~$h$ to help establish the locations of several pen positions
(see lines 12, 13, and~21 of |io.mf|).
\exercise Continuing the previous exercise, what will be the values of
$w$ and~$h$ if there are exactly 3.6 pixels per point?
\answer $8\times3.6=28.8$ rounds to the value $w=29$; similarly, $h=25$.
\ (And $d=0$.)
There's a quoted phrase |"The| |letter| |O"| at the end of line~9; this is
simply a title that will be used in printouts.
The `|endchar|' ↑↑"endchar" on line 16 finishes the character that was
begun on line~9, by writing it to an output file and possibly displaying
it on your screen. We will want
to see the positions of the control points $z↓1$, $z↓2$,
$z↓3$, and~$z↓4$ that are used in its design, together with the auxiliary
points $(z↓{1l},z↓{2l},z↓{3l},z↓{4l})$ and $(z↓{1r},z↓{2r},z↓{3r},z↓{4r})$
that come with the "penpos" conventions; the statement `|penlabels(1,2,3,4)|'
↑↑"penlabels" takes care of labelling these points on the proofsheets.
So much for the letter O. Lines 17--23 are analogous to what we've seen
before, except that there's a new wrinkle: They contain a little program
↑↑@def@ enclosed by `|def...enddef|', which means that a
{\sl↑{subroutine}\/} is being defined. In other words, those lines set up
a whole bunch of \MF\ commands that we will want to execute several times
with minor variations. The subroutine is called "test\_I" and it has three
parameters called "code", "trial\_stem", and "trial\_width" (see line~17).
The idea is that we'll want to draw several different versions of an `I',
having different stem widths and character widths; but we want to type the
program only once. Line~18 defines "stem"|#| and "stem", given a value of
"trial\_stem"; and lines 19--23 complete the program for the letter I.
\smallskip
Oops---we've been talking much too long about |io.mf|. It's time to stop
rambling and to begin Experiment~2 in earnest, because it will be much
more fun to see what the computer actually does with that file.
Are you brave enough to try Experiment 2? Sure.
Get \MF\ going again, but this time when the machine says `↑|**|' you should
say `|io|', since that's the name of the file you have prepared so
laboriously. \ (The file could also be specified by giving its full name
`|io.mf|', but \MF\ automatically adds `|.mf|' ↑↑|mf| when
no suffix has been given explicitly.)
If all goes well, the computer should now flash its lights a bit
and---presto---a big `{\manual\IOO}' should be drawn on your screen.
But if your luck is as good as the author's, something will probably go wrong
the first time, most likely because of a typographic error in the file.
A \MF\ program contains lots of data with comparatively little redundancy,
so a single error can make a drastic change in the meaning. Check that
you've typed everything perfectly: Be sure to notice the difference between
the letter~`|l|' and the numeral~`|1|' (especially in line~12, where it
says `|x1l|', not `|x11| or~`|xll|'); be sure to distinguish between
the letter~`|O|' and the numeral~`|0|' (especially in line~9); be sure to
type the ``underline'' characters in words like `|mode_setup|'. We'll see
later that \MF\ can recover gracefully from most errors, but your job for
now is to make sure that you've got |io.mf| correct.
Once you have a working file, the computer will draw you an `{\manual\IOO}'
and it will also say something like this:
\begintt
(io.mf
The letter O [79])
*
\endtt
What does this mean? Well, `|(io.mf|' means that it has started to read your
file, and `|The| |letter|~|O|' was printed when the title was found in
line~9. Then when \MF\ got to the |endchar| on line~16, it said
`|[79]|' to tell you that it had just output character number~79.
\ (This is the ↑{ASCII} code for the letter~|O|; Appendix~C lists all
of these codes, it you need to know them.) The `|)|' after `|[79]|'
means that \MF\ subsequently finished reading the file, and the `↑|*|'
means that it wants another instruction.
Hmmm. The file contains programs for both I and O; why did we get only
an~O? Answer: Because lines 17--23 simply define the subroutine "test\_I";
they don't actually do anything with that subroutine. We need to activate
"test\_I" if we're going to see what it does. So let's type
\begintt
test_I("I",5/6,1/3);
\endtt
this invokes the subroutine, with $"code"=\null$|"I"|,
$"trial\_stem"={5\over6}$, and $"trial\_width"={1\over3}$. The computer will
now draw an~I corresponding to these values,\footnote*{Unless, of course,
there was a typo in the definition of "test\_I".} and it will prompt us
for another command.
It's time to type `↑|end|' now, after which \MF\ should tell us that it has
completed this run and made an output file called `|io.gf|'. Running this
file through ↑|GFtoDVI| as in Experiment~1 will produce two proofsheets,
showing the `{\manual\IOO}' and the `{\manual\IOI}' we have created.
The output won't be shown here, but you can see the results by doing
the experiment personally.
Look at those proofsheets now, because they provide instructive examples
of the simulated broad-edge pen constructions introduced in Chapter~4.
Compare the `{\manual\IOO}' with the program that drew it: Notice that
the $\penpos2$ in line~10 makes the curve slightly thicker at the ↑↑"penpos"
bottom than at the top; that the equation `$x↓{1l}=w-x↓{3l}="curve\_sidebar"$'
in line~12 makes the right edge of the curve as far from the right of the
bounding box as the left edge is from the left; that line~13 places point~1
slightly lower than point~3. Line~22 includes a ↑"pentaper" command that moves
point $z↓{2l}$ inward, 25\%~closer than usual to point~$z↓2$, while
$z↓{2r}$ moves 10\%~closer.
\danger Your proof copy of the `{\manual\IOO}' should show twelve dots
for key points; but only ten of them will be labeled, because there isn't
room enough to put labels on points 2 and~4. The missing labels usually
appear in the upper right corner, where it might say, e.g.,
`|4|~|=|~|4l|~|+|~|(-1,-5.9)|'; this
means that point $z↓4$ is one pixel to the left and 5.9 pixels down
from point~$z↓{4l}$, which is labeled. \ (Some implementations omit this
information, because there isn't always room for it.)
The proofsheets obtained in Experiment~2 show the key points and the
bounding boxes, but this extra information can interfere with our
perception of the character shape itself. There's a simple way to
get proofs that allow a viewer to criticize the results from an aesthetic
rather than a logical standpoint; the creation of such proofs will be the
goal of our next experiment.
Here's how to do Experiment~3: Start \MF\ as usual, then type
\begintt
\mode=smoke; input io
\endtt
in response to the `↑|**|'. This will input file |io.mf| again,
after establishing ``smoke'' mode. \ (As in Experiment~1, the command line
begins with `|\|' so that the computer knows you aren't starting with
the name of a file.) \ Then complete the run exactly ↑↑{backslash}
as in Experiment~2, by typing `|test_I("I",5/6,1/3);| |end|';
and apply |GFtoDVI| to the resulting file |io.gf|.
This time the proofsheets will contain the same characters as before, but
they will be darker and without labelled points. The bounding boxes will
be indicated only by small markings at the corners; you can put these
boxes next to each other and tack the results up on the wall, then stand
back to see how the characters will look when set by a high-resolution
typesetter. \ (This way of working is called ↑"smoke" mode because it's
analogous to the ``smoke proofs'' that punch-cutters traditionally used to
test their handiwork. They held the newly cut type over a candle flame so
that it would be covered with carbon, then they pressed it on paper to
make a clean impression of the character, in order to see whether changes
were needed.)
\danger Incidentally, many systems allow you to invoke \MF\ by typing
a one-line command like `|mf|~|io|' in the case of Experiment~2; you
don't have to wait for the `|**|' before giving a file name. Similarly,
the one-liners `|mf|~|\relax|' and `|mf|~|\mode=smoke;| |input|~|io|' can be
used on many systems at the beginning of Experiments 1 and~3. You might want
to try this, to see if it works on your computer, or you might ask
somebody if there's a similar shortcut.
Experiments 1, 2, and 3 have demonstrated how to make proof drawings of
test characters, but they don't actually produce new fonts that can be
used in typesetting. For this, we move onward to Experiment~4, in which
we put ourselves in the position of a person who is just starting to
design a new typeface. Let's imagine that we're happy with the~O of
|io.mf|, and that we want a sans-serif I in the general style produced
by "test\_I", but we aren't sure about how thick the stem of the~I
should be in order to make it blend properly with the~O. Moreover, we aren't
sure how much white space to leave at the sides of the~I. So we want to do
some typesetting experiments, using a sequence of different I's.
The ideal way to do this would be to produce a high-resolution test font and to
view the output at its true size. But this may be too expensive, because fine
printing equipment is usually available only for large production runs.
The next-best alternative is to use a low-resolution printer but to magnify
the output, so that the resolution is effectively increased. We shall adopt
the latter strategy, because it gives us a chance to learn about ↑{magnification}
as well as fontmaking.
After starting \MF\ again, you can begin Experiment 4 by typing
\begintt
\mode=localfont; mag=4; input io
\endtt
in response to the `|**|'. The ↑{plain base} at your installation is supposed
to recognize ↑|localfont| as the name of the mode that makes fonts for your
``standard'' output device. The equation `|mag=4|' means that this run will
produce a font that is magnified fourfold; i.e., the results will be
4~times bigger than usual.
The computer will read |io.mf| as before, but this time it won't display an~`O';
characters are normally not displayed in fontmaking modes, because we usually
want the computer to run as fast as possible when it's generating a font
that has already been designed. All you'll see is `|(io.mf| |[79])|',
followed by~`↑|*|'. Now the fun starts: You should type
\begintt
code=100;
for s=7 upto 10:
for w=5 upto 8:
test_I(incr(code),s/10,w/20);
endfor endfor end.
\endtt
(Here `↑|upto|' must be typed as a single word.) \ We'll learn about
repeating things with `↑|for||...|↑|endfor|' in Chapter~xx. This little
program produces 16 versions of the letter~I, with stem widths of
$7\over10$, $8\over10$, $9\over10$, and~${10\over10}\pt$, and with
character widths of $5\over20$, $6\over20$, $7\over20$, and~${8\over20}\,
\rm em$. The sixteen trial characters will appear in positions 101 through~116
of the font; it turns out that these are the ↑{ASCII} codes for lower case
letters |e| through~|t| inclusive. \ (Other codes would have been used if
`|code|' had been started at a value different from~100. The instruction
`|incr(code)|' increases the value of |code| by~1 and produces the new value;
thus, each use of |test_I| has a different code value.) ↑↑"incr"
This run of \MF\ will not only produce a generic font |io.gf|, it will also
create a file called |io.tfm|, the ``↑{font metric file}'' that tells
↑↑{output of METAFONT} ↑↑|tfm|
typesetting systems like \TeX\ how to make use of the new font. The remaining
part of Experiment~4 will be to put \TeX\ to work: We shall make some test
patterns from the new font, in order to determine which `I' is best.
You may need to ask a local system wizard for help at this point, because
it may be necessary to move the file |io.tfm| to some special place where
\TeX\ and the other typesetting software can find it. Furthermore, you'll
need to run a program that converts |io.gf| to the font format used by your
local output device. But with luck, these will both be fairly simple
operations, and a new font called `|io|' will effectively be installed
on your system. This font will contain seventeen letters, namely an |O| and
sixteen |I|'s, where the |I|'s happen to be in the positions normally occupied
by |e|, |f|, \dots,~|t|. Furthermore, the font will be magnified fourfold.
You can use \TeX\ to typeset from this font like any other, but for the
purposes of Experiment~4 it's best to use a special \TeX\ package that has
been specifically designed for font testing. All you need to do is to
run \TeX---which is just like running \MF, except that you call it `|tex|'
instead of `|mf|'; and you simply type `|testfont|' in reply to \TeX's
`|**|'. \ (The |testfont| routine should be available on your system; if
not, you or somebody else can type it in, by copying the relevant material
from Appendix~H\null.) \ You will then be asked for the name of the font
you wish to test. Type
\begintt
io scaled 4000
\endtt
(which means the |io| font magnified by 4, in \TeX's jargon),
since this is what \MF\ just created. The machine will now ask you for
a test command, and you should reply
\begintt
\mixture
\endtt
to get the ``mixture'' test. \ (Don't forget the ↑{backslash}.) \ You'll be
asked for a ↑{background letter}, a starting letter, and an ending letter;
type `|O|', `|e|', and `|t|', respectively. This will produce sixteen
lines of typeset output, in which the first line contains a mixture of
|O| with~|e|, the second contains a mixture of |O|~with~|f|, and so on.
To complete Experiment~4, type `|\end|' to \TeX, and print the file
|testfont.dvi| ↑↑|dvi| that \TeX\ gives you.
\def\\{\kern1pt}\def\|{\kern.5pt}
If all goes well, you'll have sixteen lines that say
`O\|I\|OO\|I\\I\|OOO\|I\\I\\I\|O\|I',
but with a different I on each line. In order to choose the line that looks
best, without being influenced by neighboring lines, it's convenient to take
two sheets of blank paper and use them to mask out all of the lines
except the one you're studying. Caution: These letters are four times
larger than the size at which the final font is meant to be viewed,
so you should look at the samples from afar. Xerographic reductions may
introduce distortions that will give misleading results. Sometimes when
you stare at things like this too closely, they all look wrong, or
they all look right; first impressions are usually more significant
than the results of logical reflection. At any rate, you should be able
to come up with an informed judgment about what values to use for the
stem width and the character width of a decent `I'; these can then be
incorporated into the program, the `|def|' and `|enddef|' parts of
|io.mf| can be removed, and you can go on to design other characters
that go with your I and~O. Furthermore you can always go back and make
editorial changes after you see your letters in more contexts.
\dangerexercise Once you have a satisfactory `{\manual\IOI}' and
`{\manual\IOO}', add a letter `\thinspace{\manual\IOT}\thinspace' by
adapting the example at the end of Chapter~4. \ [{\sl Hint:\/} The width
should be $0.6\,$em.]
\answer It's merely necessary to supply the proper environment
by using "beginchar", etc., and by defining the appropriate
stem widths. We shouldn't use the names "thin" and "thick", which appear
already in the program for~O; the following solution assumes that the
``winning'' stem width for~I is $0.9\pt$:
\begintt
bar#:=.8pt#; stem#:=.9pt#; define_blacker_pixels(bar,stem);
beginchar("T",0.6em#,cap#,0); "The letter T";
penpos1(bar,75); penpos2(bar,72); penpos3(bar,70);
pentaper2(.4,.6);
x1l=0; x2=.5w; x3=w;
y1=y3l; y2=.5[y1,y3]; .8[y2r,y3r]=h;
penpos4(10/9stem,argd(z3-z1));
penpos5(10/9stem,20); penpos6(10/9stem,10);
z2=z4; pentaper4(.25,.1);
x5r=x4r; y5=2/3h; x6=x5; y6=0; pentaper5(.4,0);
dz5=down; penstroke(1,2,3); penstroke(4,5,6);
penlabels(1,2,3,4,5,6); endchar;
\endtt
\ddangerexercise The goddess Io was known in Egypt as Isis.
Design an `{\manual\IOS}' for her.
\answer Here's one way, using variables like "thick" and "bar"
that have already been defined in the~O or in the~T of the
\rightfig A5a ({200\apspix} x 252\apspix) ↑-69pt
previous exercise:
\begintt
beginchar("S",5/9em#,cap#,0); "The letter S";
penpos1(bar,70);
penpos2(bar,80);
penpos3(.5[bar,thick],200);
penpos5(.5[bar,thick],210);
penpos6(bar,80);
penpos7(.25[bar,thick],75);
pentaper2(.4,.6); pentaper6(.3,.5);
x1=x5; y1r=.94h+o;
x2=x4=x6=.5w; y2r=h+o; y4=.54h; y6l=-o;
x3r=.04em; y3=.5[y4,y2];
x5l=w-.03em; y5=.5[y4,y6];
.5[x7l,x7]=.04em; y7l=.1h-o;
path trial; trial=z3{down}..z4..{down}z5;
dz4=direction 1 of trial;
penpos4(thick,argd(dz4)-90);
dz3=dz5=down; dz2=dz6=left;
penstroke(1,2,3,4,5,6,7);
penlabels(1,2,3,4,5,6,7); endchar;
\endtt
Notice that the pen angle at point 4 has been found by letting \MF\
↑↑"direction" construct a ↑{trial path} through the center points,
then using the ↑{perpendicular} direction. The letters work reasonably
well at their true size: `{\manual\IOI\IOO} {\manual\IOI\IOS}
{\manual\IOI\IOS\IOI\IOS} {\manual\IOT\IOO\IOO}; {\manual\IOT\IOO\IOS\IOS}
{\manual\IOI\IOT}, {\manual\IOO\IOT\IOI\IOS}.'
Well, this isn't a book about type design; the example of |io.mf| is
simply intended to illustrate how a type designer might want to operate,
and to provide a run-through of the complete process from design of
type to its use in a document. We must go back now to the world of
computerese, and study a few more practical details about the use of \MF.
This has been a long chapter, but take heart: There's only one more
experiment to do, and then you will know enough about \MF\ to run it
fearlessly by yourself forever after. The only thing you are still missing
is some information about how to cope with error messages; sometimes
\MF\ stops and asks you what to do next. Indeed, this may have already
happened, and you may have panicked.
Error messages can be terrifying when you aren't prepared for them;
but they can be fun when you have the right attitude. Just remember that
you really haven't hurt the computer's feelings, and that nobody will
hold the errors against you. Then you'll find that running \MF\ might
actually be a creative experience instead of something to be dreaded.
The first step in Experiment 5 is to plant some intentional mistakes
in the input file. Make a copy of |io.mf| and call it |badio.mf|; then
change line~1 of |badio.mf| to
\begintt
mode setup; % an intentional error!
\endtt
(thereby omitting the underline character in |mode_setup|).
Also change the first semicolon (\thinspace`|;|'\thinspace) on line~2
to a colon (\thinspace`|:|'\thinspace);
change `|thick,10|' to `|thick,l0|' on line~10 (i.e., replace the numeral~`|1|'
by the letter~`|l|'\thinspace); and change `|thin|' to `|thinn|' on line~11.
These four changes introduce typical typographic errors, and it will be
instructive to see if they lead to any disastrous consequences.
Now start \MF\ up again; but instead of cooperating with the computer, type
`|mumble|' in reply to the~`|**|'. \ (As long as you're going to make
intentional mistakes, you might as well make some dillies.) \
\MF\ will say that it can't find any file called |mumble.mf|,
and it will ask you for another name. Just hit \<return> this time;
you'll see that you had better give the name of a real file.
So type `|badio|' and wait for \MF\ to find one of the {\sl faux pas\/}
in that messed-up text.
Ah yes, the machine will soon stop, after typing something like this:
\begintt
>> mode.setup
! Isolated expression.
<to be read again>
;
l.1 mode setup;
% an intentional error!
?
\endtt
\MF\ begins its error messages with `|!|', and it sometimes precedes them
with one or two related mathematical expressions that are displayed on
lines starting with `↑|>>|'. Each error message is also followed by lines
of context that show what the computer was reading at the time of the
error. Such context lines occur in pairs; the top line of the pair (e.g.,
`|mode| |setup;|'\thinspace) shows what \MF\ has looked at so far, and
where it came from (`|l.1|', i.e., line number~1); the bottom line (here
`|%|~|an| |intentional| |error!|'\thinspace) shows what \MF\ has yet to
read. In this case there are two pairs of context lines; the top pair
refers to a semicolon that \MF\ has read once but will be reading again,
because it didn't belong with the preceding material.
You don't have to take out pencil and paper in order to write down the
error messages that you get before they disappear from view, since \MF\
always writes a ``↑{transcript}'' or ``↑{log file}'' that records what
happened during each session. For example, you should now have a file
called |io.log| containing the transcript of Experiment~4, as well as a file
|mfput.log| that contains the transcript of Experiment~1. \ (The old
transcript of Experiment~2 was probably overwritten when you did
Experiment~3, and again when you did Experiment~4, because all three
transcripts were called |io.log|.) \ At the end of Experiment~5 you'll
have a file |badio.log| that will serve as a helpful reminder of
what errors need to be fixed up.
The `↑|?|' that appears after the context display means that \MF\ wants
advice about what to do next. If you've never seen an error message before,
or if you've forgotten what sort of response is expected, you can type
`|?|' now (go ahead and try it!); \MF\ will respond as follows:
\begintt
Type <return> to proceed, S to scroll future error messages,
R to run without stopping, Q to run quietly,
I to insert something, E to edit your file,
1 or ... or 9 to ignore the next 1 to 9 tokens of input,
H for help, X to quit.
\endtt
This is your menu of options. You may choose to continue in various ways:
\smallskip\item{1.}
Simply type \<return>. \MF\ will resume its processing, after
attempting to recover from the error as best it can.
\smallbreak\item{2.} Type `|S|'. \MF\ will proceed without
pausing for instructions if further errors arise. Subsequent error messages
will flash by on your terminal, possibly faster than you can read them, and
they will appear in your log file where you can scrutinize them at your
leisure. Thus, `|S|'~is sort of like typing \<return> to every message.
\smallbreak\item{3.} Type `|R|'. This is like `|S|' but even stronger,
since it tells \MF\ not to stop for any reason, not even if a file name
can't be found.
\smallbreak\item{4.} Type `|Q|'. This is like `|R|' but even more so,
since it tells \MF\ not only to proceed without stopping but also to
suppress all further output to your terminal. It is a fast, but somewhat
reckless, way to proceed (intended for running \MF\ with no operator in
attendance).
\smallbreak\item{5.} Type `|I|', followed by some text that you want to
insert. \MF\ will read this text before encountering what it
would ordinarily see ↑↑{inserting text online}
↑↑{online interaction, see interaction} ↑↑{interacting with MF}
next.
\smallbreak\item{6.} Type a small number (less than 100). \MF\ will
delete this many ↑{tokens} from whatever it is
about to read next, and it will pause again to give you another chance to
look things over. ↑↑{deleting tokens}
\ (A~``token'' is a name, number, or symbol that \MF\ reads as a unit;
e.g., `|mode|' and `|setup|' and `|;|' are the first three tokens
of |badio.mf|, but `|mode_setup|' is the first token of |io.mf|.
Chapter~xx explains this concept precisely.)
\smallbreak\item{7.} Type `|H|'. This is what you should do now and whenever
you are faced with an error message that you haven't seen for a~while. \MF\
has two messages built in for each perceived error: a formal one and an
informal one. The formal message is printed first (e.g., `|!|~|Isolated|
|expression.|'\thinspace); the informal one is printed if you request
more help by typing `|H|', and it also appears in your log file if you
are scrolling error messages. The informal message tries to complement the
formal one by explaining what \MF\ thinks the trouble is, and often
by suggesting a strategy for recouping your losses.↑↑{help messages}
\smallbreak\item{8.} Type `|X|'. This stands for ``exit.'' It causes \MF\
to stop working on your job, after putting the finishing touches on your
|log| file and on any characters that have already been output to your |gf|
and/or |tfm| files. The current (incomplete) character will not be output.
\smallbreak\item{9.} Type `|E|'. This is like `|X|', but it also prepares
the computer to edit the file that \MF\ is currently reading, at the
current position, so that you can conveniently make a change before
trying again.
\smallbreak\noindent
After you type `|H|' (or `|h|', which also works), you'll get a message
that tries to explain the current problem: The mathematical quantity just
read by \MF\ (i.e., |mode.setup|) was not followed by `|=|' or `|:=|', so
there was nothing for the computer to do with it. Chapter xx explains that
a space between tokens (e.g., `|mode|~|setup|'\thinspace) is equivalent to
a period between tokens (e.g., `|mode.setup|'\thinspace). The correct
spelling `|mode_setup|' would be recognized as a preloaded subroutine of
plain \MF\!, but plain \MF\ doesn't have any built-in meaning for
|mode.setup|. Hence |mode.setup| appears as a sort of orphan, and \MF\
realizes that something is amiss.
In this case it's OK to go ahead and type \<return>, because we really
don't need to do the operations of "mode\_setup" when no special mode
has been selected. \MF\ will continue by forgetting the isolated expression,
and it will ignore the rest of line~1 because everything after a
↑↑{percent} `|%|'~sign is always ignored. \ (This is another thing that
will be explained in Chapter~xx; it's a handy way to put ↑{comments}
into your \MF\ programs.) \ The changes that were made to line~1 of |badio.mf|
therefore have turned out to be relatively harmless. But \MF\ will
almost immediately encounter the mutilated semicolon in line~2:
\begintt
! Extra tokens will be flushed.
<to be read again>
:
l.2 em#:=10pt#:
cap#:=7pt#;
?
\endtt
What does this mean? Type `|H|' to find out. \MF\ has no idea what to
do with a `|:|' at this place in the file, so it plans to recover by
``↑{flushing}'' or getting rid of everything it sees, until coming to a
semicolon. It would be a bad idea to type \<return> now, since you'd lose
the important assignment `|cap#:=7pt#|', and that would lead to worse errors.
You might type `|X|' or `|E|' at this point, to exit from \MF\ and to fix
the errors in lines 1 and~2 before trying again. But it's usually best
to keep going, trying to detect and correct as many mistakes as possible
in each run, since that increases your productivity while
decreasing your computer bills. An experienced \MF\ user will quit
after an error only if the error is unfixable, or if there's almost no
chance that additional errors are present.
The solution in this case is to proceed in two steps: First type `|1|',
which tells \MF\ to delete the next token (the unwanted `|:|'); then type
`|I;|', which inserts a semicolon. This semicolon protects the rest of line~2
from being flushed away,
so all will go well until \MF\ reaches another garbled line.
The next error message is more elaborate, because it is detected while
\MF\ is trying to carry out a "penpos" command; "penpos" is not a
primitive operation (it is defined in plain \MF), hence a lot more
context is given:
\begintt
>> l0
! Improper transformation argument.
<to be read again>
;
penpos->...(EXPR3),0)rotated(EXPR4);
z(SUFFIX2)=0.5[z(SUFF...
l.10 penpos1(thick,l0)
; penpos2(.1[thin,thick],90-10);
?
\endtt
At first, such error messages will appear to be complete nonsense to you,
because much of what you see is low-level \MF\ code that you never wrote. But
you can overcome this hangup by getting a feeling for the way \MF\ operates.
The bottom line shows how much progress \MF\ has made so far in the |badio|
file: It has read `|penpos1(thick,l0)|' but not yet the semicolon, on line~10.
The "penpos" routine expands into a long list of tokens; indeed, this list
is so long that it can't all be shown on two lines, and the appearances of
`↑|...|' indicate that the definition of "penpos" has been truncated here.
Parameter values are often inserted into the expansion of a high-level
routine; in this case, for example, `|(EXPR3)|' and `|(EXPR4)|' correspond
to the respective parameters `|thick|' and `|l0|', and `|(SUFFIX2)|'
corresponds to~`|1|'. ↑↑|EXPR| ↑↑|SUFFIX|
\MF\ detected an error just after encountering the phrase `|rotated(EXPR4)|';
the value of |(EXPR4)| was an undefined quantity (namely `|l0|',
which \MF\ treats as the subscripted variable~`$l↓0$'\thinspace), and
↑{rotation} is permitted only when a known numeric value has been supplied.
Rotations are particular instances of what \MF\ calls {\sl↑{transformations}\/};
hence \MF\ describes this particular error by saying that an ``improper
transformation argument'' was present.
When you get a multiline error message like this, the best clues about the
source of the trouble are usually on the bottom line (since that is what
you typed) and on the top line (since that is what triggered the error
message). Somewhere in there you can usually spot the problem.
If you type `|H|' now, you'll find that
\MF\ has simply decided to continue without doing the requested rotation.
Thus if you respond by typing \<return>, \MF\ will go on as if the program
had said `|penpos1(thick,0)|'. Comparatively little harm has been done;
but there's actually a way to fix the error perfectly before proceeding:
Insert the correct rotation by typing
\begintt
I rotated 10
\endtt
and \MF\ will rotate by 10 degrees as if `|l0|' had been `|10|'.
What happens next in Experiment 5? \MF\ will hiccup on the remaining
bug that we planted in the file. This time, however, the typo will
not be discovered until much later, because there's nothing wrong
with line~11 as it stands. \ (The variable |thinn| is not defined,
but undefined quantities are no problem unless you're doing something
complicated like rotation. Indeed, \MF\ programs typically
consist of equations in which there are lots of unknowns;
variables get more and more defined as time goes on. Hence spelling
errors cannot possibly be detected until the last minute.) \
Finally comes the moment of truth, when |badio| tries to draw a
path through an unknown point; and you will get an error message
that's even scarier than the previous one:
\begintt
>> 0.08682thinn+144
! Undefined x coordinate has been replaced by 0.
<to be read again>
{
<for(4)> ...e:if.known.dz(SUFFIX0):{
dz(SUFFIX0)}fi.fi.fi ...
<for(l)> ...dz$:{dz$}fi.fi.fi.endfor
; ENDFOR
penstroke->...fi.fi.fi.endfor;endfor
.endgroup;if.cycle.pa...
l.15 penstroke(1,2,3,4,cycle)
;
?
\endtt
Wow; what's this? The expansion of "penstroke" involves two
@for@ loops, and the error was detected in the midst of these. The
expression `|0.08682thinn+144|' just above the error message implies that
the culprit in this case was a misspelled `|thin|'. If that hadn't been
enough information, you could have gleaned another clue from `|<for(4)>|',
which puts $z↓4$ under suspicion because it says that the current loop
value is~4.
In any event the mistake on line~11 has propagated too far to be fixable,
so you're justified in typing `|X|' or~`|E|' at this point. But type~`|S|'
instead, just for fun: This tells \MF\ to plunge ahead, correcting all
remaining errors as best it can. \ (There will be a few more problems,
since several variables still depend on `|thinn|'.) \ \MF\ will draw a
very strange letter~O before it gets to the end of the file. Then you
should type `|end|' to terminate the run.
If you try to edit |bad.io| again, you'll notice that line~2 still
contains ↑↑{editing} a colon instead of a semicolon; the fact that you
told \MF\ to delete the colon and to insert additional material doesn't
mean that your file has changed in any way. However, the transcript file
|badio.log| has a record of all the errors, so it's a handy reference when
you want to correct mistakes. \ (Why not look at
|badio.log| now, and |io.log| too, in order to get familiar with log files?)
\dangerexercise Suppose you were doing Experiment 3 with |badio| instead
of~|io|, so you began by saying `|\mode=smoke|; |input badio|'. Then you
would want to recover from the error on line~1 by inserting a correct
"mode\_setup" command, instead of by simply \<return>ing, because
"mode\_setup" is what really establishes "smoke" mode. Unfortunately if you
try typing `|I|~|mode_setup|' in response to the ``isolated expression''
error, it doesn't work. What should you type instead?
\answer After an ``isolated expression,'' \MF\ thinks it is at the end of
a statement or command, so it expects to see a semicolon next. You should
type, e.g., `|I;|~|mode_setup|' to keep \MF\ happy.
By doing the five experiments in this chapter you have learned at first hand
(1)~how to produce proofsheets of various kinds, including ``smoke proofs'';
(2)~how to make a new font and test it; (3)~how to keep calm when \MF\
issues stern warnings. Congratulations! You're on the threshold of being able to
do lots more. As you read the following chapters, the best strategy
will be for you to continue making trial runs, using experiments
of your own design.
\exercise However, this has been an extremely long chapter,
so you should go outside now and get some {\sl real\/} exercise.
\answer Yes.
\endchapter
Let us learn how Io's frenzy came---
She telling her disasters manifold.
\author \AE SCHYLUS, ↑↑{Aeschylus} %
{\sl Prometheus Bound\/} (c.\thinspace470 B.C.) % verse 801
% This is the translation by Morshead
\bigskip
To the student who wishes to use graphical methods as a tool,
it can not be emphasized too strongly that practice in the use of that tool
is as essential as a knowledge of how to use it.
The oft-repeated pedagogical phrase, ``we learn by doing,'' is applicable here.
\author THEODORE ↑{RUNNING}, {\sl Graphical Mathematics\/} (1927) % p viii
\eject
\beginchapter Appendix A. Answers to\\All the\\Exercises
The preface to this manual points out the wisdom of trying to figure out
each exercise before you look up the answer here. But these answers are intended
to be read, since they occasionally provide additional information that
you are best equipped to understand when you have just worked on a problem.
\immediate\closeout\ans % this makes the answers file ready
\ninepoint
\input answers
\endchapter
Calle these foule Offendors to their Answeres.
\author WILLIAM ↑{SHAKESPEARE}, {\sl Second Henry the Sixth\/} (1600?) %
% fixthis [2 Hen VI, II.i.203]
\bigskip
If you can't solve a problem,
you can always look up the answer.
But please, try first to solve it by yourself;
then you'll learn more and you'll learn faster.
\author DONALD E. ↑{KNUTH}, {\sl The METAFONTbook\/} (1985)
\eject
\beginchapter Appendix J. Joining the\\\TeX\ Community
This appendix is about grouping of another kind: \TeX\ and \MF\ users from
around the world have banded together to form the \TeX\ Users Group (TUG),
in order to exchange information about common problems and solutions.
A semiannual newsletter called {\sl TUGboat\/} has been published
since 1980, featuring articles about all aspects of \TeX\ and \MF. ↑↑{TeX}
TUG has a network of ``site coordinators'' who serve as focal points of
communication for people with the same computer configurations.
Occasional short courses are given in order
to provide concentrated training in special topics; videotapes of
these courses are available for rental.
Meetings of the entire TUG membership are held at least once a year.
You can buy \MF\ T-shirts at these meetings.
Information about membership in TUG and subscription to {\sl TUGboat\/}
is available from
\smallskip
{\obeylines
\TeX\ Users Group
c/o American Mathematical Society
P.O. Box 6248
Providence RI 02940, USA.
}
\endchapter
TUG is established to serve members having a common interest
in \TeX, a system for typesetting technical text,
and in\/ \MF\!, a system for font design.
\author T\kern-.15em\lower.5ex\hbox{E}\kern-.005em X %
USERS GROUP, {\sl Bylaws, Article II\/} (1983) % TUGboat 4 (1983) p60
\bigskip
Don't delay, write today! That number again is
\TeX\ Users Group
c/o American Mathematical Society
P.O. Box 6248
Providence RI 02940, USA.
\author DONALD E. ↑{KNUTH}, {\sl The \TeX book\/} (1984) % Appendix J
\eject
\end
\beginchapter Chapter X. A Chapter\\Template
Start the text here.
\endchapter
A first quotation.
\author A FIRST ↑{AUTHOR}, {\sl A First Source\/} (18xx)
\bigskip
A second quotation.
\author A SECOND ↑{AUTHOR}, {\sl A Second Source\/} (19xx)
\eject